diff options
Diffstat (limited to 'phpBB')
34 files changed, 583 insertions, 130 deletions
diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index 41d0ae8d42..eafe11ee89 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -525,7 +525,6 @@ li {  	padding: 0;  	border-right: 1px solid #CCCFD3;  	position: relative; -	z-index: 1;  }  .rtl #menu { @@ -1891,7 +1890,6 @@ li.pagination ul {  	color: #000;  	text-align: center;  	border: 1px solid #AAA; -	opacity: .95;  }  .tooltip span.top { diff --git a/phpBB/adm/style/installer_form.html b/phpBB/adm/style/installer_form.html index a38f33c7c2..592d361d1e 100644 --- a/phpBB/adm/style/installer_form.html +++ b/phpBB/adm/style/installer_form.html @@ -1,3 +1,4 @@ +<!-- IF FORM_TITLE --><h1>{FORM_TITLE}</h1><!-- ENDIF -->  <form id="<!-- IF FORM_ID -->{FORM_ID}<!-- ELSE -->install_install<!-- ENDIF -->" method="POST" action="{U_ACTION}">  <!-- IF .options -->  <!-- IF S_NOT_ONLY_BUTTON_FORM --> @@ -8,9 +9,9 @@  		<!-- IF options.S_LEGEND -->  			<!-- IF not options.S_FIRST_ROW -->  			</fieldset> - -			<fieldset>  			<!-- ENDIF --> +			<fieldset> +  		<legend>{options.LEGEND}</legend>  		<!-- ELSE -->  		<dl> @@ -49,7 +50,7 @@  <fieldset class="submit-buttons">  	<legend>{L_SUBMIT}</legend>  	<!-- BEGIN submit_buttons --> -	<input class="button1<!-- IF submit_buttons.DISABLED --> disabled<!-- ENDIF -->" type="submit" name="{submit_buttons.KEY}" value="{submit_buttons.TITLE}"<!-- IF submit_buttons.DISABLED --> disabled="disabled"<!-- ENDIF --> /> +	<input class="<!-- IF not submit_buttons.IS_SECONDARY -->button1<!-- ELSE -->button2<!-- ENDIF --><!-- IF submit_buttons.DISABLED --> disabled<!-- ENDIF -->" type="submit" name="{submit_buttons.KEY}" value="{submit_buttons.TITLE}"<!-- IF submit_buttons.DISABLED --> disabled="disabled"<!-- ENDIF --> />  	<!-- END submit_buttons -->  </fieldset>  <!-- ENDIF --> diff --git a/phpBB/adm/style/permission_mask.html b/phpBB/adm/style/permission_mask.html index 017d29d832..8b3121bfa0 100644 --- a/phpBB/adm/style/permission_mask.html +++ b/phpBB/adm/style/permission_mask.html @@ -41,7 +41,7 @@  			<dt style="width: 20%"><label for="role{p_mask.S_ROW_COUNT}{p_mask.f_mask.S_ROW_COUNT}">{L_ROLE}{L_COLON}</label></dt>  			{% if p_mask.f_mask.role_options %}  				<dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 20%"> -					<div class="dropdown-container dropdown-button-control roles-options" data-alt-text="{LA_ROLE_DESCRIPTION}"> +					<div class="dropdown-container dropdown-right dropdown-button-control roles-options" data-alt-text="{LA_ROLE_DESCRIPTION}">  						<select id="role{p_mask.S_ROW_COUNT}{p_mask.f_mask.S_ROW_COUNT}" name="role[{p_mask.f_mask.UG_ID}][{p_mask.f_mask.FORUM_ID}]">{p_mask.f_mask.S_ROLE_OPTIONS}</select>  						<span title="Roles" class="button icon-button tools-icon dropdown-trigger dropdown-select">{L_NO_ROLE_ASSIGNED}</span>  						<div class="dropdown hidden"> diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 359afb1ec4..069f9089c2 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -27,9 +27,9 @@ phpbb.isTouch = (window && typeof window.ontouchstart !== 'undefined');   */  phpbb.loadingIndicator = function() {  	if (!$loadingIndicator) { -		$loadingIndicator = $('<div />', {  -			id: 'loading_indicator',  -			class: 'loading_indicator',  +		$loadingIndicator = $('<div />', { +			'id': 'loading_indicator', +			'class': 'loading_indicator'  		});  		$loadingIndicator.appendTo('#page-footer');  	} diff --git a/phpBB/composer.json b/phpBB/composer.json index 5bc8f5dc0d..926fad5188 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -33,7 +33,7 @@  		"marc1706/fast-image-size": "^1.1",  		"paragonie/random_compat": "^1.4",  		"patchwork/utf8": "^1.1", -		"s9e/text-formatter": "~0.11.0", +		"s9e/text-formatter": "~0.13.0",  		"symfony/config": "^2.8",  		"symfony/console": "^2.8",  		"symfony/debug": "^2.8", @@ -69,7 +69,7 @@  	},  	"config": {  		"platform": { -			"php": "5.4" +			"php": "5.4.7"  		}  	}  } diff --git a/phpBB/composer.lock b/phpBB/composer.lock index c1bdf26e02..59143a1fa7 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -4,8 +4,8 @@          "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",          "This file is @generated automatically"      ], -    "hash": "7c30306b2abcb79a206bf6497ef45a02", -    "content-hash": "d559dd0af2317fb0fc15720a18834e33", +    "hash": "f14915a2ccaf76ccd6d3ea725721a8a8", +    "content-hash": "c843abc1344cd9df37f63c08a125cad0",      "packages": [          {              "name": "bantu/ini-get-wrapper", @@ -661,27 +661,27 @@          },          {              "name": "s9e/text-formatter", -            "version": "0.11.2", +            "version": "0.13.1",              "source": {                  "type": "git",                  "url": "https://github.com/s9e/TextFormatter.git", -                "reference": "735a56076e29348d838ce6c2658996daae86718f" +                "reference": "804ed8fdfa9fd0c8d99f5a33000d4f7e5ed90c6f"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/735a56076e29348d838ce6c2658996daae86718f", -                "reference": "735a56076e29348d838ce6c2658996daae86718f", +                "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/804ed8fdfa9fd0c8d99f5a33000d4f7e5ed90c6f", +                "reference": "804ed8fdfa9fd0c8d99f5a33000d4f7e5ed90c6f",                  "shasum": ""              },              "require": {                  "ext-dom": "*",                  "ext-filter": "*",                  "lib-pcre": ">=7.2", -                "php": ">=5.3.3" +                "php": ">=5.4.7"              },              "require-dev": {                  "matthiasmullie/minify": "*", -                "php": ">=5.3.3", +                "php": ">=5.4.7",                  "s9e/regexp-builder": ">=1.3.0"              },              "suggest": { @@ -722,7 +722,7 @@                  "parser",                  "shortcodes"              ], -            "time": "2017-10-02 16:58:51" +            "time": "2017-12-10 00:55:53"          },          {              "name": "symfony/config", @@ -3577,6 +3577,6 @@      },      "platform-dev": [],      "platform-overrides": { -        "php": "5.4" +        "php": "5.4.7"      }  } diff --git a/phpBB/config/default/container/services_text_formatter.yml b/phpBB/config/default/container/services_text_formatter.yml index a9f2efdb16..74624ea4e4 100644 --- a/phpBB/config/default/container/services_text_formatter.yml +++ b/phpBB/config/default/container/services_text_formatter.yml @@ -26,6 +26,11 @@ services:      text_formatter.utils:          alias: text_formatter.s9e.utils +    text_formatter.s9e.bbcode_merger: +        class: phpbb\textformatter\s9e\bbcode_merger +        arguments: +            - '@text_formatter.s9e.factory' +      text_formatter.s9e.factory:          class: phpbb\textformatter\s9e\factory          arguments: diff --git a/phpBB/docs/CREDITS.txt b/phpBB/docs/CREDITS.txt index 2df7543ce1..cb42779641 100644 --- a/phpBB/docs/CREDITS.txt +++ b/phpBB/docs/CREDITS.txt @@ -26,9 +26,11 @@ phpBB Lead Developer:    Marc (Marc Alexander)  phpBB Developers:        bantu (Andreas Fischer)                           CHItA (Máté Bartus) +                         Derky (Derk Ruitenbeek)                           Elsensee (Oliver Schramm) +                         Hanakin (Michael Miday) +                         MichaelC (Michael Cullum)                           Nicofuma (Tristan Darricau) -                         prototech (Cesar Gallegos)  For a list of phpBB Team members, please see:  http://www.phpbb.com/about/team/ @@ -61,6 +63,7 @@ phpBB Developers:        A_Jelly_Doughnut (Josh Woody) [01/2010 - 11/2010]                           kellanved (Henry Sudhof)      [04/2007 - 03/2011]                           nickvergessen (Joas Schilling)[04/2010 - 12/2015]                           Oleg (Oleg Pudeyev)           [01/2011 - 05/2013] +                         prototech (Cesar Gallegos)    [01/2014 - 12/2016]                           rxu (Ruslan Uzdenov)          [04/2010 - 12/2012]                           TerraFrost (Jim Wigginton)    [04/2009 - 01/2011]                           ToonArmy (Chris Smith)        [06/2008 - 11/2011] diff --git a/phpBB/download/file.php b/phpBB/download/file.php index a9cd4a3b3c..9ee489cef4 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -159,6 +159,8 @@ $user->session_begin(false);  $auth->acl($user->data);  $user->setup('viewtopic'); +$phpbb_content_visibility = $phpbb_container->get('content.visibility'); +  if (!$config['allow_attachments'] && !$config['allow_pm_attach'])  {  	send_status_line(404, 'Not Found'); @@ -225,7 +227,7 @@ else  			$post_row = $db->sql_fetchrow($result);  			$db->sql_freeresult($result); -			if (!$post_row || ($post_row['post_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $post_row['forum_id']))) +			if (!$post_row || !$phpbb_content_visibility->is_visible('post', $post_row['forum_id'], $post_row))  			{  				// Attachment of a soft deleted post and the user is not allowed to see the post  				send_status_line(404, 'Not Found'); diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 5b31417b83..4c390c5f0e 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -1355,18 +1355,18 @@ class acp_styles  		}  		// Hardcoded template bitfield to add for new templates +		$default_bitfield = '1111111111111'; +  		$bitfield = new bitfield(); -		$bitfield->set(0); -		$bitfield->set(1); -		$bitfield->set(2); -		$bitfield->set(3); -		$bitfield->set(4); -		$bitfield->set(8); -		$bitfield->set(9); -		$bitfield->set(11); -		$bitfield->set(12); -		$value = $bitfield->get_base64(); -		return $value; +		for ($i = 0; $i < strlen($default_bitfield); $i++) +		{ +			if ($default_bitfield[$i] == '1') +			{ +				$bitfield->set($i); +			} +		} + +		return $bitfield->get_base64();  	}  } diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 090cb32ebb..beaa1d11f1 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -2497,7 +2497,7 @@ class acp_users  							'U_DELETE'			=> $this->u_action . "&action=delete&u=$user_id&g=" . $data['group_id'],  							'U_APPROVE'			=> ($group_type == 'pending') ? $this->u_action . "&action=approve&u=$user_id&g=" . $data['group_id'] : '', -							'GROUP_NAME'		=> ($group_type == 'special') ? $user->lang['G_' . $data['group_name']] : $data['group_name'], +							'GROUP_NAME'		=> $group_helper->get_name($data['group_name']),  							'L_DEMOTE_PROMOTE'	=> ($data['group_leader']) ? $user->lang['GROUP_DEMOTE'] : $user->lang['GROUP_PROMOTE'],  							'S_IS_MEMBER'		=> ($group_type != 'pending') ? true : false, diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index e00be1e01a..e3af294b75 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -662,6 +662,8 @@ function phpbb_increment_downloads($db, $ids)  */  function phpbb_download_handle_forum_auth($db, $auth, $topic_id)  { +	global $phpbb_container; +  	$sql_array = array(  		'SELECT'	=> 't.topic_visibility, t.forum_id, f.forum_name, f.forum_password, f.parent_id',  		'FROM'		=> array( @@ -677,7 +679,9 @@ function phpbb_download_handle_forum_auth($db, $auth, $topic_id)  	$row = $db->sql_fetchrow($result);  	$db->sql_freeresult($result); -	if ($row && $row['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) +	$phpbb_content_visibility = $phpbb_container->get('content.visibility'); + +	if ($row && !$phpbb_content_visibility->is_visible('topic', $row['forum_id'], $row))  	{  		send_status_line(404, 'Not Found');  		trigger_error('ERROR_NO_ATTACHMENT'); diff --git a/phpBB/includes/functions_mcp.php b/phpBB/includes/functions_mcp.php index dfe3fefbd0..7ab2da8e5c 100644 --- a/phpBB/includes/functions_mcp.php +++ b/phpBB/includes/functions_mcp.php @@ -197,7 +197,7 @@ function phpbb_get_topic_data($topic_ids, $acl_list = false, $read_tracking = fa  */  function phpbb_get_post_data($post_ids, $acl_list = false, $read_tracking = false)  { -	global $db, $auth, $config, $user; +	global $db, $auth, $config, $user, $phpbb_container;  	$rowset = array(); @@ -246,6 +246,8 @@ function phpbb_get_post_data($post_ids, $acl_list = false, $read_tracking = fals  	$result = $db->sql_query($sql);  	unset($sql_array); +	$phpbb_content_visibility = $phpbb_container->get('content.visibility'); +  	while ($row = $db->sql_fetchrow($result))  	{  		if ($acl_list && !$auth->acl_gets($acl_list, $row['forum_id'])) @@ -253,7 +255,7 @@ function phpbb_get_post_data($post_ids, $acl_list = false, $read_tracking = fals  			continue;  		} -		if ($row['post_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) +		if (!$phpbb_content_visibility->is_visible('post', $row['forum_id'], $row))  		{  			// Moderators without the permission to approve post should at least not see them. ;)  			continue; diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 594100ac65..a7a93d6115 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -166,7 +166,7 @@ class ucp_register  					->format($user->lang['DATE_FORMAT'], true);  				unset($now); -				$template->assign_vars(array( +				$template_vars = array(  					'S_LANG_OPTIONS'	=> (sizeof($lang_row) > 1) ? language_select($user_lang) : '',  					'L_COPPA_NO'		=> sprintf($user->lang['UCP_COPPA_BEFORE'], $coppa_birthday),  					'L_COPPA_YES'		=> sprintf($user->lang['UCP_COPPA_ON_AFTER'], $coppa_birthday), @@ -180,11 +180,11 @@ class ucp_register  					'COOKIE_NAME'		=> $config['cookie_name'],  					'COOKIE_PATH'		=> $config['cookie_path'], -				)); +				);  			}  			else  			{ -				$template->assign_vars(array( +				$template_vars = array(  					'S_LANG_OPTIONS'	=> (sizeof($lang_row) > 1) ? language_select($user_lang) : '',  					'L_TERMS_OF_USE'	=> sprintf($user->lang['TERMS_OF_USE_CONTENT'], $config['sitename'], generate_board_url()), @@ -195,11 +195,32 @@ class ucp_register  					'COOKIE_NAME'		=> $config['cookie_name'],  					'COOKIE_PATH'		=> $config['cookie_path'], -					)  				);  			} + +			$tpl_name = 'ucp_agreement'; + +			/** +			* Allows to modify the agreements. +			* +			* @event core.ucp_register_agreement_modify_template_data +			* @var	string	tpl_name			Template file +			* @var	array	template_vars		Array with data about to be assigned to the template +			* @var	array	s_hidden_fields		Array with hidden form elements +			* @var	array	lang_row			Array with available languages, read only +			* @since 3.2.2-RC1 +			*/ +			$vars = array('tpl_name', 'template_vars', 's_hidden_fields', 'lang_row'); +			extract($phpbb_dispatcher->trigger_event('core.ucp_register_agreement_modify_template_data', compact($vars))); +  			unset($lang_row); +			$template_vars = array_merge($template_vars, array( +				'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields), +			)); + +			$template->assign_vars($template_vars); +  			/**  			* Allows to modify the agreements.  			* @@ -207,10 +228,11 @@ class ucp_register  			*  			* @event core.ucp_register_agreement  			* @since 3.1.6-RC1 +			* @deprecated 3.2.2-RC1 Replaced by core.ucp_register_agreement_modify_template_data and to be removed in 3.3.0-RC1  			*/  			$phpbb_dispatcher->dispatch('core.ucp_register_agreement'); -			$this->tpl_name = 'ucp_agreement'; +			$this->tpl_name = $tpl_name;  			return;  		} @@ -505,7 +527,6 @@ class ucp_register  		{  			$s_hidden_fields = array_merge($s_hidden_fields, $captcha->get_hidden_fields());  		} -		$s_hidden_fields = build_hidden_fields($s_hidden_fields);  		// Visual Confirmation - Show images  		if ($config['enable_confirm']) @@ -531,8 +552,7 @@ class ucp_register  		// Assign template vars for timezone select  		phpbb_timezone_select($template, $user, $data['tz'], true); -		$template->assign_vars(array( -			'ERROR'				=> (sizeof($error)) ? implode('<br />', $error) : '', +		$template_vars = array(  			'USERNAME'			=> $data['username'],  			'PASSWORD'			=> $data['new_password'],  			'PASSWORD_CONFIRM'	=> $data['password_confirm'], @@ -547,13 +567,41 @@ class ucp_register  			'S_CONFIRM_REFRESH'	=> ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false,  			'S_REGISTRATION'	=> true,  			'S_COPPA'			=> $coppa, -			'S_HIDDEN_FIELDS'	=> $s_hidden_fields,  			'S_UCP_ACTION'		=> append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'),  			'COOKIE_NAME'		=> $config['cookie_name'],  			'COOKIE_PATH'		=> $config['cookie_path'], +		); + +		$tpl_name = 'ucp_register'; + +		/** +		* Modify template data on the registration page +		* +		* @event core.ucp_register_modify_template_data +		* @var	array	template_vars		Array with template data +		* @var	array	data				Array with user data, read only +		* @var	array	error				Array with errors +		* @var	array	s_hidden_fields		Array with hidden field elements +		* @var	string	tpl_name			Template name +		* @since 3.2.2-RC1 +		*/ +		$vars = array( +			'template_vars', +			'data', +			'error', +			's_hidden_fields', +			'tpl_name', +		); +		extract($phpbb_dispatcher->trigger_event('core.ucp_register_modify_template_data', compact($vars))); + +		$template_vars = array_merge($template_vars, array( +			'ERROR'				=> (sizeof($error)) ? implode('<br />', $error) : '', +			'S_HIDDEN_FIELDS'	=> build_hidden_fields($s_hidden_fields),  		)); +		$template->assign_vars($template_vars); +  		//  		$user->profile_fields = array(); @@ -561,8 +609,7 @@ class ucp_register  		$cp->generate_profile_fields('register', $user->get_iso_lang_id());  		// -		$this->tpl_name = 'ucp_register'; -		$this->page_title = 'UCP_REGISTRATION'; +		$this->tpl_name = $tpl_name;  	}  	/** diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index fa61f45366..f97ba7ac07 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -478,7 +478,7 @@ INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order)  INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NEW_MEMBER', 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER', 'f_', 10);  # -- phpbb_styles -INSERT INTO phpbb_styles (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Limited', 1, 'prosilver', 'kNg=', 0, ''); +INSERT INTO phpbb_styles (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Limited', 1, 'prosilver', '//g=', 0, '');  # -- Forums  INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents) VALUES ('{L_FORUMS_FIRST_CATEGORY}', '', 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 'Admin', 'AA0000', 972086460, '', '', '', '', '', '', '', 0, 0, ''); diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php index 1655855edb..505d12e8ff 100644 --- a/phpBB/language/en/cli.php +++ b/phpBB/language/en/cli.php @@ -117,6 +117,7 @@ $lang = array_merge($lang, array(  	'CLI_EXTENSION_ENABLE_FAILURE'		=> 'Could not enable extension %s',  	'CLI_EXTENSION_ENABLE_SUCCESS'		=> 'Successfully enabled extension %s',  	'CLI_EXTENSION_ENABLED'				=> 'Extension %s is already enabled', +	'CLI_EXTENSION_NOT_EXIST'			=> 'Extension %s does not exist',  	'CLI_EXTENSION_NAME'				=> 'Name of the extension',  	'CLI_EXTENSION_PURGE_FAILURE'		=> 'Could not purge extension %s',  	'CLI_EXTENSION_PURGE_SUCCESS'		=> 'Successfully purged extension %s', diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index f92de0069c..a6f5b10e86 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -37,6 +37,13 @@ class enable extends command  		$io = new SymfonyStyle($input, $output);  		$name = $input->getArgument('extension-name'); + +		if (!$this->manager->is_available($name)) +		{ +			$io->error($this->user->lang('CLI_EXTENSION_NOT_EXIST', $name)); +			return 1; +		} +  		$extension = $this->manager->get_extension($name);  		if (!$extension->is_enableable()) diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index bf7dc2c703..237300894b 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -131,6 +131,42 @@ class content_visibility  		return (int) $data[$mode . '_approved'] + (int) $data[$mode . '_unapproved'] + (int) $data[$mode . '_softdeleted'];  	} + +	/** +	* Check topic/post visibility for a given forum ID +	* +	* Note: Read permissions are not checked. +	* +	* @param $mode		string	Either "topic" or "post" +	* @param $forum_id	int		The forum id is used for permission checks +	* @param $data		array	Array with item information to check visibility +	* @return bool		True if the item is visible, false if not +	*/ +	public function is_visible($mode, $forum_id, $data) +	{ +		$is_visible = $this->auth->acl_get('m_approve', $forum_id) || $data[$mode . '_visibility'] == ITEM_APPROVED; + +		/** +		* Allow changing the result of calling is_visible +		* +		* @event core.phpbb_content_visibility_is_visible +		* @var	bool		is_visible			Default visibility condition, to be modified by extensions if needed. +		* @var	string		mode				Either "topic" or "post" +		* @var	int			forum_id			Forum id of the current item +		* @var	array		data				Array of item information +		* @since 3.2.2-RC1 +		*/ +		$vars = array( +			'is_visible', +			'mode', +			'forum_id', +			'data', +		); +		extract($this->phpbb_dispatcher->trigger_event('core.phpbb_content_visibility_is_visible', compact($vars))); + +		return $is_visible; +	} +  	/**  	* Create topic/post visibility SQL for a given forum ID  	* @@ -176,10 +212,14 @@ class content_visibility  		if ($this->auth->acl_get('m_approve', $forum_id))  		{ -			return $where_sql . '1 = 1'; +			$where_sql .= '1 = 1'; +		} +		else +		{ +			$where_sql .= $table_alias . $mode . '_visibility = ' . ITEM_APPROVED;  		} -		return $where_sql . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED; +		return '(' . $where_sql . ')';  	}  	/** @@ -195,16 +235,21 @@ class content_visibility  	*/  	public function get_forums_visibility_sql($mode, $forum_ids = array(), $table_alias = '')  	{ -		$where_sql = '('; +		$where_sql = ''; -		$approve_forums = array_intersect($forum_ids, array_keys($this->auth->acl_getf('m_approve', true))); +		$approve_forums = array_keys($this->auth->acl_getf('m_approve', true)); +		if (!empty($forum_ids) && !empty($approve_forums)) +		{ +			$approve_forums = array_intersect($forum_ids, $approve_forums); +			$forum_ids = array_diff($forum_ids, $approve_forums); +		}  		$get_forums_visibility_sql_overwrite = false;  		/**  		* Allow changing the result of calling get_forums_visibility_sql  		*  		* @event core.phpbb_content_visibility_get_forums_visibility_before -		* @var	string		where_sql							The action the user tried to execute +		* @var	string		where_sql							Extra visibility conditions. It must end with either an SQL "AND" or an "OR"  		* @var	string		mode								Either "topic" or "post" depending on the query this is being used in  		* @var	array		forum_ids							Array of forum ids which the posts/topics are limited to  		* @var	string		table_alias							Table alias to prefix in SQL queries @@ -229,33 +274,13 @@ class content_visibility  			return $get_forums_visibility_sql_overwrite;  		} -		if (sizeof($approve_forums)) -		{ -			// Remove moderator forums from the rest -			$forum_ids = array_diff($forum_ids, $approve_forums); - -			if (!sizeof($forum_ids)) -			{ -				// The user can see all posts/topics in all specified forums -				return $where_sql . $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums) . ')'; -			} -			else -			{ -				// Moderator can view all posts/topics in some forums -				$where_sql .= $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums) . ' OR '; -			} -		} -		else -		{ -			// The user is just a normal user -			return $where_sql . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ' -				AND ' . $this->db->sql_in_set($table_alias . 'forum_id', $forum_ids, false, true) . ')'; -		} - +		// Moderator can view all posts/topics in the moderated forums +		$where_sql .= '(' . $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums, false, true) . ' OR '; +		// Normal user can view approved items only  		$where_sql .= '(' . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ' -			AND ' . $this->db->sql_in_set($table_alias . 'forum_id', $forum_ids) . '))'; +			AND ' . $this->db->sql_in_set($table_alias . 'forum_id', $forum_ids, false, true) . '))'; -		return $where_sql; +		return '(' . $where_sql . ')';  	}  	/** @@ -281,12 +306,12 @@ class content_visibility  		* Allow changing the result of calling get_global_visibility_sql  		*  		* @event core.phpbb_content_visibility_get_global_visibility_before -		* @var	array		where_sqls							The action the user tried to execute +		* @var	array		where_sqls							Array of extra visibility conditions. Will be joined by imploding with "OR".  		* @var	string		mode								Either "topic" or "post" depending on the query this is being used in  		* @var	array		exclude_forum_ids					Array of forum ids the current user doesn't have access to  		* @var	string		table_alias							Table alias to prefix in SQL queries  		* @var	array		approve_forums						Array of forums where the user has m_approve permissions -		* @var	string		visibility_sql_overwrite	Forces the function to return an implosion of where_sqls (joined by "OR") +		* @var	string		visibility_sql_overwrite			If not empty, forces the function to return visibility_sql_overwrite after executing the event  		* @since 3.1.3-RC1  		*/  		$vars = array( @@ -304,24 +329,17 @@ class content_visibility  			return $visibility_sql_overwrite;  		} -		if (sizeof($exclude_forum_ids)) -		{ -			$where_sqls[] = '(' . $this->db->sql_in_set($table_alias . 'forum_id', $exclude_forum_ids, true) . ' -				AND ' . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ')'; -		} -		else -		{ -			$where_sqls[] = $table_alias . $mode . '_visibility = ' . ITEM_APPROVED; -		} +		// Include approved items in all forums but the excluded +		$where_sqls[] = '(' . $this->db->sql_in_set($table_alias . 'forum_id', $exclude_forum_ids, true, true) . ' +			AND ' . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ')'; +		// If user has moderator permissions, add everything in the moderated forums  		if (sizeof($approve_forums))  		{  			$where_sqls[] = $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums); -			return '(' . implode(' OR ', $where_sqls) . ')';  		} -		// There is only one element, so we just return that one -		return $where_sqls[0]; +		return '(' . implode(' OR ', $where_sqls) . ')';  	}  	/** @@ -437,12 +455,13 @@ class content_visibility  		 * @var			int			topic_id		Topic of the post IDs to be modified.  		 * @var			int			forum_id		Forum ID that the topic_id resides in.  		 * @var			int			user_id			User ID doing this action. -		 * @var			int			timestamp		Timestamp of this action. +		 * @var			int			time			Timestamp of this action.  		 * @var			string		reason			Reason specified by the user for this change.  		 * @var			bool		is_starter		Are we changing the topic's starter?  		 * @var			bool		is_latest		Are we changing the topic's latest post?  		 * @var			array		data			The data array for this action.  		 * @since 3.1.10-RC1 +		 * @changed 3.2.2-RC1 Use time instead of non-existent timestamp  		 */  		$vars = array(  			'visibility', @@ -450,7 +469,7 @@ class content_visibility  			'topic_id',  			'forum_id',  			'user_id', -			'timestamp', +			'time',  			'reason',  			'is_starter',  			'is_latest', @@ -622,12 +641,13 @@ class content_visibility  		 * @var			int			topic_id		Topic of the post IDs to be modified.  		 * @var			int			forum_id		Forum ID that the topic_id resides in.  		 * @var			int			user_id			User ID doing this action. -		 * @var			int			timestamp		Timestamp of this action. +		 * @var			int			time			Timestamp of this action.  		 * @var			string		reason			Reason specified by the user for this change.  		 * @var			bool		is_starter		Are we changing the topic's starter?  		 * @var			bool		is_latest		Are we changing the topic's latest post?  		 * @var			array		data			The data array for this action.  		 * @since 3.1.10-RC1 +		 * @changed 3.2.2-RC1 Use time instead of non-existent timestamp  		 */  		$vars = array(  			'visibility', @@ -635,7 +655,7 @@ class content_visibility  			'topic_id',  			'forum_id',  			'user_id', -			'timestamp', +			'time',  			'reason',  			'is_starter',  			'is_latest', @@ -709,18 +729,19 @@ class content_visibility  		 * @var			int			topic_id			Topic of the post IDs to be modified.  		 * @var			int			forum_id			Forum ID that the topic_id resides in.  		 * @var			int			user_id				User ID doing this action. -		 * @var			int			timestamp			Timestamp of this action. +		 * @var			int			time				Timestamp of this action.  		 * @var			string		reason				Reason specified by the user for this change.  		 * @var			bool		force_update_all	Force an update on all posts within the topic, regardless of their current approval state.  		 * @var			array		data				The data array for this action.  		 * @since 3.1.10-RC1 +		 * @changed 3.2.2-RC1 Use time instead of non-existent timestamp  		 */  		$vars = array(  			'visibility',  			'topic_id',  			'forum_id',  			'user_id', -			'timestamp', +			'time',  			'reason',  			'force_update_all',  			'data', @@ -758,18 +779,19 @@ class content_visibility  		 * @var			int			topic_id			Topic of the post IDs to be modified.  		 * @var			int			forum_id			Forum ID that the topic_id resides in.  		 * @var			int			user_id				User ID doing this action. -		 * @var			int			timestamp			Timestamp of this action. +		 * @var			int			time				Timestamp of this action.  		 * @var			string		reason				Reason specified by the user for this change.  		 * @var			bool		force_update_all	Force an update on all posts within the topic, regardless of their current approval state.  		 * @var			array		data				The data array for this action.  		 * @since 3.1.10-RC1 +		 * @changed 3.2.2-RC1 Use time instead of non-existent timestamp  		 */  		$vars = array(  			'visibility',  			'topic_id',  			'forum_id',  			'user_id', -			'timestamp', +			'time',  			'reason',  			'force_update_all',  			'data', diff --git a/phpBB/phpbb/db/migration/data/v32x/merge_duplicate_bbcodes.php b/phpBB/phpbb/db/migration/data/v32x/merge_duplicate_bbcodes.php new file mode 100644 index 0000000000..3bf442bab5 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/merge_duplicate_bbcodes.php @@ -0,0 +1,75 @@ +<?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\v32x; + +class merge_duplicate_bbcodes extends \phpbb\db\migration\migration +{ +	public function update_data() +	{ +		return [ +			['custom', [[$this, 'update_bbcodes_table']]], +		]; +	} + +	public function update_bbcodes_table() +	{ +		$sql     = 'SELECT bbcode_id, bbcode_tag, bbcode_helpline, bbcode_match, bbcode_tpl FROM ' . BBCODES_TABLE; +		$result  = $this->sql_query($sql); +		$bbcodes = []; +		while ($row = $this->db->sql_fetchrow($result)) +		{ +			$variant = (substr($row['bbcode_tag'], -1) === '=') ? 'with': 'without'; +			$bbcode_name = rtrim($row['bbcode_tag'], '='); +			$bbcodes[$bbcode_name][$variant] = $row; +		} +		$this->db->sql_freeresult($result); + +		foreach ($bbcodes as $bbcode_name => $variants) +		{ +			if (count($variants) === 2) +			{ +				$this->merge_bbcodes($variants['without'], $variants['with']); +			} +		} +	} + +	protected function merge_bbcodes(array $without, array $with) +	{ +		$merged = $this->container->get('text_formatter.s9e.bbcode_merger')->merge_bbcodes( +			[ +				'usage'    => $without['bbcode_match'], +				'template' => $without['bbcode_tpl'] +			], +			[ +				'usage'    => $with['bbcode_match'], +				'template' => $with['bbcode_tpl'] +			] +		); +		$bbcode_data = [ +			'bbcode_tag'      => $without['bbcode_tag'], +			'bbcode_helpline' => $without['bbcode_helpline'] . ' | ' . $with['bbcode_helpline'], +			'bbcode_match'    => $merged['usage'], +			'bbcode_tpl'      => $merged['template'] +		]; + +		$sql = 'UPDATE ' . BBCODES_TABLE . ' +			SET ' . $this->db->sql_build_array('UPDATE', $bbcode_data) . ' +			WHERE bbcode_id = ' . $without['bbcode_id']; +		$this->sql_query($sql); + +		$sql = 'DELETE FROM ' . BBCODES_TABLE . ' +			WHERE bbcode_id = ' . $with['bbcode_id']; +		$this->sql_query($sql); +	} +} diff --git a/phpBB/phpbb/db/migration/data/v32x/update_prosilver_bitfield.php b/phpBB/phpbb/db/migration/data/v32x/update_prosilver_bitfield.php new file mode 100644 index 0000000000..6e51a01834 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/update_prosilver_bitfield.php @@ -0,0 +1,39 @@ +<?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\v32x; + +class update_prosilver_bitfield extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v32x\v321', +		); +	} + +	public function update_data() +	{ +		return array( +			array('custom', array(array($this, 'update_bbcode_bitfield'))), +		); +	} + +	public function update_bbcode_bitfield() +	{ +		$sql = 'UPDATE ' . STYLES_TABLE . " +			SET bbcode_bitfield = '//g=' +			WHERE style_path = 'prosilver'"; +		$this->sql_query($sql); +	} +} diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index bce0149890..dd584eff30 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -187,6 +187,7 @@ class ajax_iohandler extends iohandler_base  			$tpl_ary['KEY'] = $input_name;  			$tpl_ary['S_EXPLAIN'] = false;  			$tpl_ary['DISABLED'] = isset($input_options['disabled']) ? $input_options['disabled'] : false; +			$tpl_ary['IS_SECONDARY'] = isset($input_options['is_secondary']) ? $input_options['is_secondary'] : false;  			if (isset($input_options['default']))  			{ @@ -218,6 +219,11 @@ class ajax_iohandler extends iohandler_base  			$this->template->assign_block_vars($block_name, $tpl_ary);  		} +		if (isset($form['database_update_submit']) && !$form['database_update_submit']['disabled']) +		{ +			$this->template->assign_var('FORM_TITLE', $this->language->lang('UPDATE_CONTINUE_UPDATE_PROCESS')); +		} +  		$this->template->assign_var('S_NOT_ONLY_BUTTON_FORM', $not_button_form);  		if (!$not_button_form) diff --git a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php index 1792a3b723..8151a24f2d 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php @@ -103,8 +103,8 @@ class diff_files extends task_base  		$old_path = $this->update_helper->get_path_to_old_update_files();  		$new_path = $this->update_helper->get_path_to_new_update_files(); -		$files_to_diff = $this->installer_config->get('update_files', array()); -		$files_to_diff = $files_to_diff['update_with_diff']; +		$update_files = $this->installer_config->get('update_files', array()); +		$files_to_diff = $update_files['update_with_diff'];  		// Set progress bar  		$this->iohandler->set_task_count(count($files_to_diff), true); @@ -154,7 +154,6 @@ class diff_files extends task_base  				}  				$diff = new \diff3($file_contents[0], $file_contents[1], $file_contents[2]); -				unset($file_contents);  				// Handle conflicts  				if ($diff->get_num_conflicts() !== 0) @@ -162,12 +161,20 @@ class diff_files extends task_base  					$merge_conflicts[] = $filename;  				} -				// Save merged output -				$this->cache->put( -					'_file_' . md5($filename), -					base64_encode(implode("\n", $diff->merged_output())) -				); +				if ($diff->merged_output() !== $file_contents[1]) +				{ +					// Save merged output +					$this->cache->put( +						'_file_' . md5($filename), +						base64_encode(implode("\n", $diff->merged_output())) +					); +				} +				else +				{ +					unset($update_files['update_with_diff'][$key]); +				} +				unset($file_contents);  				unset($diff);  			}  			else @@ -199,6 +206,16 @@ class diff_files extends task_base  				$this->installer_config->set('merge_conflict_list', $merge_conflicts);  				$this->installer_config->set('file_diff_update_count', $progress_count); +				foreach ($update_files as $type => $files) +				{ +					if (empty($files)) +					{ +						unset($update_files[$type]); +					} +				} + +				$this->installer_config->set('update_files', $update_files); +  				// Request refresh  				throw new resource_limit_reached_exception();  			} @@ -206,6 +223,16 @@ class diff_files extends task_base  		$this->iohandler->finish_progress('ALL_FILES_DIFFED');  		$this->installer_config->set('merge_conflict_list', $merge_conflicts); + +		foreach ($update_files as $type => $files) +		{ +			if (empty($files)) +			{ +				unset($update_files[$type]); +			} +		} + +		$this->installer_config->set('update_files', $update_files);  	}  	/** diff --git a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php index 21aa93b7ea..0b83e9a79d 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php @@ -99,13 +99,14 @@ class download_updated_files extends task_base  			// Add form to continue update  			$this->iohandler->add_user_form_group('UPDATE_CONTINUE_UPDATE_PROCESS', array(  				'update_recheck_files_submit'	=> array( -					'label'	=> 'UPDATE_RECHECK_UPDATE_FILES', -					'type'	=> 'submit', +					'label'			=> 'UPDATE_RECHECK_UPDATE_FILES', +					'type'			=> 'submit', +					'is_secondary'	=> empty($file_update_info),  				),  				'database_update_submit'	=> array(  					'label'		=> 'UPDATE_CONTINUE_UPDATE_PROCESS',  					'type'		=> 'submit', -					'disabled'	=> count($file_update_info) > 0, +					'disabled'	=> !empty($file_update_info),  				),  			)); diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index da1aad1c3a..c8df1951e3 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -591,6 +591,7 @@ class fulltext_mysql extends \phpbb\search\base  			WHERE MATCH ($sql_match) AGAINST ('" . $this->db->sql_escape(htmlspecialchars_decode($this->search_query)) . "' IN BOOLEAN MODE)  				$sql_where_options  			ORDER BY $sql_sort"; +		$this->db->sql_return_on_error(true);  		$result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);  		while ($row = $this->db->sql_fetchrow($result)) @@ -602,7 +603,7 @@ class fulltext_mysql extends \phpbb\search\base  		$id_ary = array_unique($id_ary);  		// if the total result count is not cached yet, retrieve it from the db -		if (!$result_count) +		if (!$result_count && count($id_ary))  		{  			$sql_found_rows = 'SELECT FOUND_ROWS() as result_count';  			$result = $this->db->sql_query($sql_found_rows); @@ -1004,6 +1005,11 @@ class fulltext_mysql extends \phpbb\search\base  			}  		} +		if (!isset($this->stats['post_text'])) +		{ +			$this->db->sql_query('ALTER TABLE ' . POSTS_TABLE . ' ADD FULLTEXT post_text (post_text)'); +		} +  		$this->db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE);  		return false; @@ -1039,6 +1045,11 @@ class fulltext_mysql extends \phpbb\search\base  			$alter[] = 'DROP INDEX post_content';  		} +		if (isset($this->stats['post_text'])) +		{ +			$alter[] = 'DROP INDEX post_text'; +		} +  		if (sizeof($alter))  		{  			$this->db->sql_query('ALTER TABLE ' . POSTS_TABLE . ' ' . implode(', ', $alter)); @@ -1059,7 +1070,7 @@ class fulltext_mysql extends \phpbb\search\base  			$this->get_stats();  		} -		return isset($this->stats['post_subject']) && isset($this->stats['post_content']); +		return isset($this->stats['post_subject']) && isset($this->stats['post_content']) && isset($this->stats['post_text']);  	}  	/** @@ -1103,6 +1114,10 @@ class fulltext_mysql extends \phpbb\search\base  				{  					$this->stats['post_subject'] = $row;  				} +				else if ($row['Key_name'] == 'post_text') +				{ +					$this->stats['post_text'] = $row; +				}  				else if ($row['Key_name'] == 'post_content')  				{  					$this->stats['post_content'] = $row; diff --git a/phpBB/phpbb/textformatter/s9e/bbcode_merger.php b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php new file mode 100644 index 0000000000..72b1473751 --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php @@ -0,0 +1,180 @@ +<?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\textformatter\s9e; + +use phpbb\textformatter\s9e\factory; +use s9e\TextFormatter\Configurator\Helpers\TemplateHelper; +use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; + +class bbcode_merger +{ +	/** +	* @var \s9e\TextFormatter\Configurator $configurator Configurator instance used to inspect BBCodes +	*/ +	protected $configurator; + +	/** +	* @param \phpbb\textformatter\s9e\factory $factory +	*/ +	public function __construct(factory $factory) +	{ +		$this->configurator = $factory->get_configurator(); +	} + +	/** +	* Merge two BBCode definitions +	* +	* All of the arrays contain a "usage" element and a "template" element +	* +	* @param  array $without BBCode definition without an attribute +	* @param  array $with    BBCode definition with an attribute +	* @return array          Merged definition +	*/ +	public function merge_bbcodes(array $without, array $with) +	{ +		$without = $this->create_bbcode($without); +		$with    = $this->create_bbcode($with); + +		// Select the appropriate strategy for merging this BBCode +		if ($this->is_content_bbcode($without, $with)) +		{ +			$merged = $this->merge_content_bbcode($without, $with); +		} +		else +		{ +			$merged = $this->merge_optional_bbcode($without, $with); +		} + +		$merged['template'] = $this->normalize_template($merged['template']); + +		return $merged; +	} + +	/** +	* Create a custom BBCode for inspection +	* +	* @param  array $definition Original BBCode definition +	* @return array             Updated definition containing a BBCode object and a Tag +	*/ +	protected function create_bbcode(array $definition) +	{ +		$bbcode = $this->configurator->BBCodes->addCustom( +			$definition['usage'], +			new UnsafeTemplate($definition['template']) +		); + +		$definition['bbcode'] = $bbcode; +		$definition['tag']    = $this->configurator->tags[$bbcode->tagName]; + +		return $definition; +	} + +	/** +	* Indent given template for readability +	* +	* @param  string $template +	* @return string +	*/ +	protected function indent_template($template) +	{ +		$dom = TemplateHelper::loadTemplate($template); +		$dom->formatOutput = true; +		$template = TemplateHelper::saveTemplate($dom); + +		// Remove the first level of indentation if the template starts with whitespace +		if (preg_match('(^\\n +)', $template, $m)) +		{ +			$template = str_replace($m[0], "\n", $template); +		} + +		return trim($template); +	} + +	/** +	* Test whether the two definitions form a "content"-style BBCode +	* +	* Such BBCodes include the [URL] BBCode, which uses its text content as +	* attribute if none is provided +	* +	* @param  array $without BBCode definition without an attribute +	* @param  array $with    BBCode definition with an attribute +	* @return array          Merged definition +	*/ +	protected function is_content_bbcode(array $without, array $with) +	{ +		// Test whether we find the same non-TEXT token between "]" and "[" in the usage +		// as between ">" and "<" in the template +		return (preg_match('(\\]\\s*(\\{(?!TEXT)[^}]+\\})\\s*\\[)', $without['usage'], $m) +			&& preg_match('(>[^<]*?' . preg_quote($m[1]) . '[^>]*?<)s', $without['template'])); +	} + +	/** +	* Merge the two BBCode definitions of a "content"-style BBCode +	* +	* @param  array $without BBCode definition without an attribute +	* @param  array $with    BBCode definition with an attribute +	* @return array          Merged definition +	*/ +	protected function merge_content_bbcode(array $without, array $with) +	{ +		// Convert [X={X}] into [X={X;useContent}] +		$usage = preg_replace('(\\})', ';useContent}', $with['usage'], 1); + +		// Use the template from the definition that uses an attribute +		$template = $with['tag']->template; + +		return ['usage' => $usage, 'template' => $template]; +	} + +	/** +	* Merge the two BBCode definitions of a BBCode with an optional argument +	* +	* Such BBCodes include the [QUOTE] BBCode, which takes an optional argument +	* but otherwise does not behave differently +	* +	* @param  array $without BBCode definition without an attribute +	* @param  array $with    BBCode definition with an attribute +	* @return array          Merged definition +	*/ +	protected function merge_optional_bbcode(array $without, array $with) +	{ +		// Convert [X={X}] into [X={X?}] +		$usage = preg_replace('(\\})', '?}', $with['usage'], 1); + +		// Build a template for both versions +		$template = '<xsl:choose><xsl:when test="@' . $with['bbcode']->defaultAttribute . '">' . $with['tag']->template . '</xsl:when><xsl:otherwise>' . $without['tag']->template . '</xsl:otherwise></xsl:choose>'; + +		return ['usage' => $usage, 'template' => $template]; +	} + +	/** +	* Normalize a template +	* +	* @param  string $template +	* @return string +	*/ +	protected function normalize_template($template) +	{ +		// Normalize the template to simplify it +		$template = $this->configurator->templateNormalizer->normalizeTemplate($template); + +		// Convert xsl:value-of elements back to {L_} tokens where applicable +		$template = preg_replace('(<xsl:value-of select="\\$(L_\\w+)"/>)', '{$1}', $template); + +		// Beautify the template +		$template = $this->indent_template($template); + +		return $template; +	} +} diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index d5ad8283d9..1e85856898 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -78,7 +78,7 @@ class factory implements \phpbb\textformatter\cache_interface  		'b'     => '[B]{TEXT}[/B]',  		'code'  => '[CODE lang={IDENTIFIER;optional}]{TEXT}[/CODE]',  		'color' => '[COLOR={COLOR}]{TEXT}[/COLOR]', -		'email' => '[EMAIL={EMAIL;useContent} subject={TEXT;optional;postFilter=rawurlencode} body={TEXT;optional;postFilter=rawurlencode}]{TEXT}[/EMAIL]', +		'email' => '[EMAIL={EMAIL;useContent} subject={TEXT1;optional;postFilter=rawurlencode} body={TEXT2;optional;postFilter=rawurlencode}]{TEXT}[/EMAIL]',  		'flash' => '[FLASH={NUMBER1},{NUMBER2} width={NUMBER1;postFilter=#flashwidth} height={NUMBER2;postFilter=#flashheight} url={URL;useContent} /]',  		'i'     => '[I]{TEXT}[/I]',  		'img'   => '[IMG src={IMAGEURL;useContent}]', @@ -266,12 +266,13 @@ class factory implements \phpbb\textformatter\cache_interface  			->addParameterByName('logger')  			->addParameterByName('max_img_height')  			->addParameterByName('max_img_width') -			->markAsSafeAsURL(); +			->markAsSafeAsURL() +			->setJS('UrlFilter.filter');  		// Add default BBCodes  		foreach ($this->get_default_bbcodes($configurator) as $bbcode)  		{ -			$configurator->BBCodes->addCustom($bbcode['usage'], $bbcode['template']); +			$configurator->BBCodes->addCustom($bbcode['usage'], new UnsafeTemplate($bbcode['template']));  		}  		if (isset($configurator->tags['QUOTE']))  		{ @@ -355,8 +356,6 @@ class factory implements \phpbb\textformatter\cache_interface  		$configurator->registeredVars['max_img_width'] = 0;  		// Load the Emoji plugin and modify its tag's template to obey viewsmilies -		$configurator->Emoji->omitImageSize(); -		$configurator->Emoji->useSVG();  		$tag = $configurator->Emoji->getTag();  		$tag->template = '<xsl:choose><xsl:when test="$S_VIEWSMILIES">' . str_replace('class="emoji"', 'class="emoji smilies"', $tag->template) . '</xsl:when><xsl:otherwise><xsl:value-of select="."/></xsl:otherwise></xsl:choose>'; diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 05ddfffa11..3698dca224 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -13,7 +13,7 @@  namespace phpbb\textformatter\s9e; -use s9e\TextFormatter\Parser\BuiltInFilters; +use s9e\TextFormatter\Parser\AttributeFilters\UrlFilter;  use s9e\TextFormatter\Parser\Logger;  /** @@ -196,7 +196,7 @@ class parser implements \phpbb\textformatter\parser_interface  	public function get_errors()  	{  		$errors = array(); -		foreach ($this->parser->getLogger()->get() as $entry) +		foreach ($this->parser->getLogger()->getLogs() as $entry)  		{  			list(, $msg, $context) = $entry; @@ -365,7 +365,7 @@ class parser implements \phpbb\textformatter\parser_interface  	static public function filter_img_url($url, array $url_config, Logger $logger, $max_height, $max_width)  	{  		// Validate the URL -		$url = BuiltInFilters::filterUrl($url, $url_config, $logger); +		$url = UrlFilter::filter($url, $url_config, $logger);  		if ($url === false)  		{  			return false; diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index 27d7bc1f27..2ee6ea2cb3 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -153,8 +153,8 @@ abstract class base implements reparser_interface  		{  			// Look for the closing tag inside of a e element, in an element of the same name, e.g.  			// <e>[/url]</e></URL> -			$match = '<e>[/' . $bbcode . ']</e></' . strtoupper($bbcode) . '>'; -			if (strpos($record['text'], $match) !== false) +			$match = '<e>[/' . $bbcode . ']</e></' . $bbcode . '>'; +			if (stripos($record['text'], $match) !== false)  			{  				return true;  			} diff --git a/phpBB/search.php b/phpBB/search.php index 0d9b2bbfe8..eabb1fc96e 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -932,6 +932,26 @@ if ($keywords || $author || $author_id || $search_id || $submit)  			while ($row = $db->sql_fetchrow($result))  			{ +				/** +				* Modify the row of a post result before the post_text is trimmed +				* +				* @event core.search_modify_post_row +				* @var	string	hilit					String to highlight +				* @var	array	row						Array with the post data +				* @var	string	u_hilit					Highlight string to be injected into URL +				* @var	string	view					Search results view mode +				* @var	array	zebra					Array with zebra data for the current user +				* @since 3.2.2-RC1 +				*/ +				$vars = array( +					'hilit', +					'row', +					'u_hilit', +					'view', +					'zebra', +				); +				extract($phpbb_dispatcher->trigger_event('core.search_modify_post_row', compact($vars))); +  				// We pre-process some variables here for later usage  				$row['post_text'] = censor_text($row['post_text']); diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg index 2deceef788..ea4e899109 100644 --- a/phpBB/styles/prosilver/style.cfg +++ b/phpBB/styles/prosilver/style.cfg @@ -25,7 +25,7 @@ style_version = 3.2.1  phpbb_version = 3.2.1  # Defining a different template bitfield -# template_bitfield = lNg= +# template_bitfield = //g=  # Parent style  # Set value to empty or to this style's name if this style does not have a parent style diff --git a/phpBB/styles/prosilver/template/ucp_footer.html b/phpBB/styles/prosilver/template/ucp_footer.html index f2f1a68db3..eb07f52e05 100644 --- a/phpBB/styles/prosilver/template/ucp_footer.html +++ b/phpBB/styles/prosilver/template/ucp_footer.html @@ -9,6 +9,4 @@  </form>  <!-- ENDIF --> -<!-- INCLUDE jumpbox.html --> -  <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index cd420b7614..807633864c 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -529,6 +529,7 @@ blockquote .codebox {  /* Attachments  ----------------------------------------*/  .attachbox { +	font-size: 13px;  	float: left;  	width: auto;  	max-width: 100%; diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 79d75a18f8..e4cf08d548 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -538,7 +538,7 @@ if ($forum_data['forum_type'] == FORUM_POST)  	while ($row = $db->sql_fetchrow($result))  	{ -		if ($row['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) +		if (!$phpbb_content_visibility->is_visible('topic', $row['forum_id'], $row))  		{  			// Do not display announcements that are waiting for approval or soft deleted.  			continue; diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 3f117eef6b..9037918a20 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -268,7 +268,7 @@ $forum_id = (int) $topic_data['forum_id'];  $user->page['forum'] = $forum_id;  // Now we know the forum_id and can check the permissions -if ($topic_data['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $forum_id)) +if (!$phpbb_content_visibility->is_visible('topic', $forum_id, $topic_data))  {  	trigger_error('NO_TOPIC');  }  | 
