diff options
63 files changed, 1120 insertions, 191 deletions
| diff --git a/.travis.yml b/.travis.yml index fa2a86c0db..4cef1af10e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,4 +53,4 @@ script:    - sh -c "if [ '$SLOWTESTS' != '1' -a '$DB' = 'mysqli' ]; then phpBB/vendor/bin/phpunit tests/lint_test.php; fi"    - sh -c "if [ '$NOTESTS' != '1' -a '$SLOWTESTS' != '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --verbose --stop-on-error; fi"    - sh -c "if [ '$SLOWTESTS' = '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --group slow; fi" -  - sh -c "set -x;if [ '$NOTESTS' = '1' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; fi" +  - sh -c "set -x;if [ '$NOTESTS' = '1' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git remote set-branches --add origin $TRAVIS_BRANCH && git fetch && git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..$TRAVIS_PULL_REQUEST_SHA; fi" diff --git a/phpBB/adm/style/acp_prune_forums.html b/phpBB/adm/style/acp_prune_forums.html index b8c681ea00..ef3880e851 100644 --- a/phpBB/adm/style/acp_prune_forums.html +++ b/phpBB/adm/style/acp_prune_forums.html @@ -94,7 +94,9 @@  		<dd><label><input type="radio" class="radio" name="prune_sticky" value="1" /> {L_YES}</label>  			<label><input type="radio" class="radio" id="sticky" name="prune_sticky" value="0" checked="checked" /> {L_NO}</label></dd>  	</dl> -	 + +	<!-- EVENT acp_prune_forums_settings_append --> +  	<p class="quick">  		{S_HIDDEN_FIELDS}  		{S_FORM_TOKEN} 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/docs/events.md b/phpBB/docs/events.md index 14183c6957..ac50ea150d 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -433,6 +433,13 @@ acp_prune_forums_prepend  * Since: 3.1.7-RC1  * Purpose: Add content before the forum select form label +acp_prune_forums_settings_append +=== +* Locations: +    + adm/style/acp_prune_forums.html +* Since: 3.2.2-RC1 +* Purpose: Add content after the prune settings +  acp_prune_users_find_username_append  ===  * Locations: 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_board.php b/phpBB/includes/acp/acp_board.php index 77e6133fe6..d2a4262e36 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -444,11 +444,11 @@ class acp_board  						'legend1'				=> 'GENERAL_SETTINGS',  						'email_enable'			=> array('lang' => 'ENABLE_EMAIL',			'validate' => 'bool',	'type' => 'radio:enabled_disabled', 'explain' => true),  						'board_email_form'		=> array('lang' => 'BOARD_EMAIL_FORM',		'validate' => 'bool',	'type' => 'radio:enabled_disabled', 'explain' => true), -						'email_function_name'	=> array('lang' => 'EMAIL_FUNCTION_NAME',	'validate' => 'string',	'type' => 'text:20:50', 'explain' => true),  						'email_package_size'	=> array('lang' => 'EMAIL_PACKAGE_SIZE',	'validate' => 'int:0',	'type' => 'number:0:99999', 'explain' => true),  						'board_contact'			=> array('lang' => 'CONTACT_EMAIL',			'validate' => 'email',	'type' => 'email:25:100', 'explain' => true),  						'board_contact_name'	=> array('lang' => 'CONTACT_EMAIL_NAME',	'validate' => 'string',	'type' => 'text:25:50', 'explain' => true),  						'board_email'			=> array('lang' => 'ADMIN_EMAIL',			'validate' => 'email',	'type' => 'email:25:100', 'explain' => true), +						'email_force_sender'	=> array('lang' => 'EMAIL_FORCE_SENDER',	'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true),  						'board_email_sig'		=> array('lang' => 'EMAIL_SIG',				'validate' => 'string',	'type' => 'textarea:5:30', 'explain' => true),  						'board_hide_emails'		=> array('lang' => 'BOARD_HIDE_EMAILS',		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true),  						'send_test_email'		=> array('lang' => 'SEND_TEST_EMAIL',		'validate' => 'bool',	'type' => 'custom', 'method' => 'send_test_email', 'explain' => true), @@ -532,13 +532,6 @@ class acp_board  			$this->new_config[$config_name] = $config_value = $cfg_array[$config_name]; -			if ($config_name == 'email_function_name') -			{ -				$this->new_config['email_function_name'] = trim(str_replace(array('(', ')'), array('', ''), $this->new_config['email_function_name'])); -				$this->new_config['email_function_name'] = (empty($this->new_config['email_function_name']) || !function_exists($this->new_config['email_function_name'])) ? 'mail' : $this->new_config['email_function_name']; -				$config_value = $this->new_config['email_function_name']; -			} -  			if ($submit)  			{  				if (strpos($data['type'], 'password') === 0 && $config_value === '********') diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index d37050869a..a8c0dd060d 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -55,7 +55,7 @@ class acp_prune  	*/  	function prune_forums($id, $mode)  	{ -		global $db, $user, $auth, $template, $phpbb_log, $request; +		global $db, $user, $auth, $template, $phpbb_log, $request, $phpbb_dispatcher;  		$all_forums = $request->variable('all_forums', 0);  		$forum_id = $request->variable('f', array(0)); @@ -165,7 +165,7 @@ class acp_prune  			}  			else  			{ -				confirm_box(false, $user->lang['PRUNE_FORUM_CONFIRM'], build_hidden_fields(array( +				$hidden_fields = array(  					'i'				=> $id,  					'mode'			=> $mode,  					'submit'		=> 1, @@ -177,7 +177,19 @@ class acp_prune  					'prune_old_polls'	=> $request->variable('prune_old_polls', 0),  					'prune_announce'	=> $request->variable('prune_announce', 0),  					'prune_sticky'		=> $request->variable('prune_sticky', 0), -				))); +				); + +				/** +				 * Use this event to pass data from the prune form to the confirmation screen +				 * +				 * @event core.prune_forums_settings_confirm +				 * @var array	hidden_fields	Hidden fields that are passed through the confirm screen +				 * @since 3.2.2-RC1 +				 */ +				$vars = array('hidden_fields'); +				extract($phpbb_dispatcher->trigger_event('core.prune_forums_settings_confirm', compact($vars))); + +				confirm_box(false, $user->lang['PRUNE_FORUM_CONFIRM'], build_hidden_fields($hidden_fields));  			}  		} @@ -217,13 +229,25 @@ class acp_prune  			$l_selected_forums = (sizeof($forum_id) == 1) ? 'SELECTED_FORUM' : 'SELECTED_FORUMS'; -			$template->assign_vars(array( +			$template_data = array(  				'L_SELECTED_FORUMS'		=> $user->lang[$l_selected_forums],  				'U_ACTION'				=> $this->u_action,  				'U_BACK'				=> $this->u_action,  				'FORUM_LIST'			=> $forum_list, -				'S_HIDDEN_FIELDS'		=> $s_hidden_fields) +				'S_HIDDEN_FIELDS'		=> $s_hidden_fields,  			); + +			/** +			 * Event to add/modify prune forums settings template data +			 * +			 * @event core.prune_forums_settings_template_data +			 * @var array	template_data	Array with form template data +			 * @since 3.2.2-RC1 +			 */ +			$vars = array('template_data'); +			extract($phpbb_dispatcher->trigger_event('core.prune_forums_settings_template_data', compact($vars))); + +			$template->assign_vars($template_data);  		}  	} 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_admin.php b/phpBB/includes/functions_admin.php index 1ad41156f9..96916e1e43 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2369,6 +2369,16 @@ function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync  		$topic_list = array_unique($topic_list);  	} +	/** +	 * Perform additional actions before topic deletion via pruning +	 * +	 * @event core.prune_delete_before +	 * @var int[]	topic_list		The IDs of the topics to be deleted +	 * @since 3.2.2-RC1 +	 */ +	$vars = array('topic_list'); +	extract($phpbb_dispatcher->trigger_event('core.prune_delete_before', compact($vars))); +  	return delete_topics('topic_id', $topic_list, $auto_sync, 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/functions_messenger.php b/phpBB/includes/functions_messenger.php index ab7f00a65a..4eda5ac6cb 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -416,7 +416,7 @@ class messenger  		switch ($type)  		{  			case 'EMAIL': -				$message = '<strong>EMAIL/' . (($config['smtp_delivery']) ? 'SMTP' : 'PHP/' . $config['email_function_name'] . '()') . '</strong>'; +				$message = '<strong>EMAIL/' . (($config['smtp_delivery']) ? 'SMTP' : 'PHP/mail()') . '</strong>';  			break;  			default: @@ -1839,7 +1839,8 @@ function phpbb_mail($to, $subject, $msg, $headers, $eol, &$err_msg)  	// On some PHP Versions mail() *may* fail if there are newlines within the subject.  	// Newlines are used as a delimiter for lines in mail_encode() according to RFC 2045 section 6.8.  	// Because PHP can't decide what is wanted we revert back to the non-RFC-compliant way of separating by one space (Use '' as parameter to mail_encode() results in SPACE used) -	$result = $config['email_function_name']($to, mail_encode($subject, ''), wordwrap(utf8_wordwrap($msg), 997, "\n", true), $headers); +	$additional_parameters = $config['email_force_sender'] ? '-f' . $config['board_email'] : ''; +	$result = mail($to, mail_encode($subject, ''), wordwrap(utf8_wordwrap($msg), 997, "\n", true), $headers, $additional_parameters);  	$collector->uninstall();  	$err_msg = $collector->format_errors(); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index c746bd0e4c..175cdeeda8 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -272,8 +272,8 @@ function user_add($user_row, $cp_data = false, $notifications_data = null)  	* Use this event to modify the values to be inserted when a user is added  	*  	* @event core.user_add_modify_data -	* @var array	user_row			Array of user details submited to user_add -	* @var array	cp_data				Array of Custom profile fields submited to user_add +	* @var array	user_row			Array of user details submitted to user_add +	* @var array	cp_data				Array of Custom profile fields submitted to user_add  	* @var array	sql_ary				Array of data to be inserted when a user is added  	* @var array	notifications_data	Array of notification data to be inserted when a user is added  	* @since 3.1.0-a1 @@ -376,6 +376,19 @@ function user_add($user_row, $cp_data = false, $notifications_data = null)  		);  	} +	/** +	* Modify the notifications data to be inserted in the database when a user is added +	* +	* @event core.user_add_modify_notifications_data +	* @var array	user_row			Array of user details submitted to user_add +	* @var array	cp_data				Array of Custom profile fields submitted to user_add +	* @var array	sql_ary				Array of data to be inserted when a user is added +	* @var array	notifications_data	Array of notification data to be inserted when a user is added +	* @since 3.2.2-RC1 +	*/ +	$vars = array('user_row', 'cp_data', 'sql_ary', 'notifications_data'); +	extract($phpbb_dispatcher->trigger_event('core.user_add_modify_notifications_data', compact($vars))); +  	// Subscribe user to notifications if necessary  	if (!empty($notifications_data))  	{ @@ -388,12 +401,12 @@ function user_add($user_row, $cp_data = false, $notifications_data = null)  	}  	/** -	* Event that returns user id, user detals and user CPF of newly registared user +	* Event that returns user id, user details and user CPF of newly registered user  	*  	* @event core.user_add_after -	* @var int		user_id			User id of newly registared user -	* @var array	user_row		Array of user details submited to user_add -	* @var array	cp_data			Array of Custom profile fields submited to user_add +	* @var int		user_id			User id of newly registered user +	* @var array	user_row		Array of user details submitted to user_add +	* @var array	cp_data			Array of Custom profile fields submitted to user_add  	* @since 3.1.0-b5  	*/  	$vars = array('user_id', 'user_row', 'cp_data'); diff --git a/phpBB/includes/questionnaire/questionnaire.php b/phpBB/includes/questionnaire/questionnaire.php index 9699843db4..ee6d0ee2a6 100644 --- a/phpBB/includes/questionnaire/questionnaire.php +++ b/phpBB/includes/questionnaire/questionnaire.php @@ -337,7 +337,7 @@ class phpbb_questionnaire_phpbb_data_provider  			'edit_time' => true,  			'email_check_mx' => true,  			'email_enable' => true, -			'email_function_name' => true, +			'email_force_sender' => true,  			'email_package_size' => true,  			'enable_confirm' => true,  			'enable_pm_icons' => true, 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..9d1236f340 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -103,7 +103,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('extension_force_un  INSERT INTO phpbb_config (config_name, config_value) VALUES ('delete_time', '0');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_check_mx', '1');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_enable', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_function_name', 'mail'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_force_sender', '0');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_max_chunk_size', '50');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_package_size', '20');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_confirm', '1'); @@ -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/acp/board.php b/phpBB/language/en/acp/board.php index f6e7a310a8..25d70813f6 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -552,8 +552,8 @@ $lang = array_merge($lang, array(  $lang = array_merge($lang, array(  	'ACP_EMAIL_SETTINGS_EXPLAIN'	=> 'This information is used when the board sends emails to your users. Please ensure the email address you specify is valid, any bounced or undeliverable messages will likely be sent to that address. If your host does not provide a native (PHP based) email service you can instead send messages directly using SMTP. This requires the address of an appropriate server (ask your provider if necessary). If the server requires authentication (and only if it does) enter the necessary username, password and authentication method.', -	'ADMIN_EMAIL'					=> 'Return email address', -	'ADMIN_EMAIL_EXPLAIN'			=> 'This will be used as the return address on all emails, the technical contact email address. It will always be used as the <samp>Return-Path</samp> and <samp>Sender</samp> address in emails.', +	'ADMIN_EMAIL'					=> 'From email address', +	'ADMIN_EMAIL_EXPLAIN'			=> 'This will be used as the from address on all emails, the technical contact email address. It will always be used as the <samp>Sender</samp> address in emails.',  	'BOARD_EMAIL_FORM'				=> 'Users send email via board',  	'BOARD_EMAIL_FORM_EXPLAIN'		=> 'Instead of showing the users email address users are able to send emails via the board.',  	'BOARD_HIDE_EMAILS'				=> 'Hide email addresses', @@ -562,8 +562,8 @@ $lang = array_merge($lang, array(  	'CONTACT_EMAIL_EXPLAIN'			=> 'This address will be used whenever a specific contact point is needed, e.g. spam, error output, etc. It will always be used as the <samp>From</samp> and <samp>Reply-To</samp> address in emails.',  	'CONTACT_EMAIL_NAME'			=> 'Contact name',  	'CONTACT_EMAIL_NAME_EXPLAIN'	=> 'This is the contact name that e-mail recipients will see. If you don’t want to have a contact name, leave this field empty.', -	'EMAIL_FUNCTION_NAME'			=> 'Email function name', -	'EMAIL_FUNCTION_NAME_EXPLAIN'	=> 'The email function used to send mails through PHP.', +	'EMAIL_FORCE_SENDER'			=> 'Force from email address', +	'EMAIL_FORCE_SENDER_EXPLAIN'	=> 'This will set the <samp>Return-Path</samp> to the from email address instead of using the local user and hostname of the server. This setting does not apply when using SMTP.<br><em><strong>Warning:</strong> Requires the user that the webserver runs as to be added as trusted user to the sendmail configuration.</em>',  	'EMAIL_PACKAGE_SIZE'			=> 'Email package size',  	'EMAIL_PACKAGE_SIZE_EXPLAIN'	=> 'This is the number of maximum emails sent out in one package. This setting is applied to the internal message queue; set this value to 0 if you have problems with non-delivered notification emails.',  	'EMAIL_SIG'						=> 'Email signature', 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/datetime.php b/phpBB/phpbb/datetime.php index 63cdba90fd..4b799b6219 100644 --- a/phpBB/phpbb/datetime.php +++ b/phpBB/phpbb/datetime.php @@ -60,6 +60,12 @@ class datetime extends \DateTime  	public function format($format = '', $force_absolute = false)  	{  		$format		= $format ? $format : $this->user->date_format; + +		if (substr($this->user->lang_name, 0,2) != 'en') +		{ +			$format = preg_replace('/([^\\\])S/','$1', $format); +		} +  		$format		= self::format_cache($format, $this->user);  		$relative	= ($format['is_short'] && !$force_absolute);  		$now		= new self($this->user, 'now', $this->user->timezone); diff --git a/phpBB/phpbb/db/migration/data/v32x/email_force_sender.php b/phpBB/phpbb/db/migration/data/v32x/email_force_sender.php new file mode 100644 index 0000000000..5319b7f76e --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/email_force_sender.php @@ -0,0 +1,37 @@ +<?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 email_force_sender extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v32x\v321', +		); +	} + +	public function effectively_installed() +	{ +		return isset($this->config['email_force_sender']); +	} + +	public function update_data() +	{ +		return array( +			array('config.add', array('email_force_sender', '0')), +			array('config.remove', array('email_function_name')), +		); +	} +} 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');  } diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php index 8e6328d1d3..764376a945 100644 --- a/tests/functional/posting_test.php +++ b/tests/functional/posting_test.php @@ -235,7 +235,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case  		));  		$crawler = self::submit($form);  		$this->assertContains( -			'<span style="font-weight: bold">My signature</span>', +			'<strong class="text-strong">My signature</strong>',  			$crawler->filter('#preview .signature')->html()  		);  	} diff --git a/tests/text_formatter/s9e/bbcode_merger_test.php b/tests/text_formatter/s9e/bbcode_merger_test.php new file mode 100644 index 0000000000..815539056b --- /dev/null +++ b/tests/text_formatter/s9e/bbcode_merger_test.php @@ -0,0 +1,280 @@ +<?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. +* +*/ + +class phpbb_textformatter_s9e_bbcode_merger_test extends phpbb_test_case +{ +	/** +	* @dataProvider get_merge_bbcodes_tests +	*/ +	public function test_merge_bbcodes($usage_without, $template_without, $usage_with, $template_with, $expected_usage, $expected_template) +	{ +		$container     = $this->get_test_case_helpers()->set_s9e_services(); +		$factory       = $container->get('text_formatter.s9e.factory'); +		$bbcode_merger = new \phpbb\textformatter\s9e\bbcode_merger($factory); + +		$without = ['usage' => $usage_without, 'template' => $template_without]; +		$with    = ['usage' => $usage_with,    'template' => $template_with]; +		$merged  = $bbcode_merger->merge_bbcodes($without, $with); + +		// Normalize the expected template's whitespace to match the default indentation +		$expected_template = str_replace("\n\t\t\t\t", "\n", $expected_template); +		$expected_template = str_replace("\t",         '  ', $expected_template); + +		$this->assertSame($expected_usage,    $merged['usage']); +		$this->assertSame($expected_template, $merged['template']); +	} + +	public function get_merge_bbcodes_tests() +	{ +		return [ +			[ +				'[x]{TEXT}[/x]', +				'<b>{TEXT}</b>', + +				'[x={TEXT1}]{TEXT}[/x]', +				'<b title="{TEXT1}">{TEXT}</b>', + +				'[x={TEXT1?}]{TEXT}[/x]', +				'<b> +					<xsl:if test="@x"> +						<xsl:attribute name="title"> +							<xsl:value-of select="@x"/> +						</xsl:attribute> +					</xsl:if> +					<xsl:apply-templates/> +				</b>' +			], +			[ +				// The tokens' numbering differs between versions +				'[x]{TEXT}[/x]', +				'<b>{TEXT}</b>', + +				'[x={TEXT1}]{TEXT2}[/x]', +				'<b title="{TEXT1}">{TEXT2}</b>', + +				'[x={TEXT1?}]{TEXT2}[/x]', +				'<b> +					<xsl:if test="@x"> +						<xsl:attribute name="title"> +							<xsl:value-of select="@x"/> +						</xsl:attribute> +					</xsl:if> +					<xsl:apply-templates/> +				</b>' +			], +			[ +				'[x]{URL}[/x]', +				'<a href="{URL}">{URL}</a>', + +				'[x={URL}]{TEXT}[/x]', +				'<a href="{URL}">{TEXT}</a>', + +				'[x={URL;useContent}]{TEXT}[/x]', +				'<a href="{@x}"> +					<xsl:apply-templates/> +				</a>' +			], +			[ +				'[x]{URL}[/x]', +				'<a href="{URL}">{L_GO_TO}: {URL}</a>', + +				'[x={URL}]{TEXT}[/x]', +				'<a href="{URL}">{L_GO_TO}: {TEXT}</a>', + +				'[x={URL;useContent}]{TEXT}[/x]', +				'<a href="{@x}">{L_GO_TO}: <xsl:apply-templates/></a>' +			], +			[ +				// Test that unsafe BBCodes can still be merged +				'[script]{TEXT}[/script]', +				'<script>{TEXT}</script>', + +				'[script={TEXT1}]{TEXT2}[/script]', +				'<script type="{TEXT1}">{TEXT2}</script>', + +				'[script={TEXT1?}]{TEXT2}[/script]', +				'<script> +					<xsl:if test="@script"> +						<xsl:attribute name="type"> +							<xsl:value-of select="@script"/> +						</xsl:attribute> +					</xsl:if> +					<xsl:apply-templates/> +				</script>' +			], +			[ +				// https://www.phpbb.com/community/viewtopic.php?p=14848281#p14848281 +				'[note]{TEXT}[/note]', +				'<span class="prime_bbcode_note_spur" onmouseover="show_note(this);" onmouseout="hide_note(this);" onclick="lock_note(this);"></span><span class="prime_bbcode_note">{TEXT}</span>', + +				'[note={TEXT1}]{TEXT2}[/note]', +				'<span class="prime_bbcode_note_text" onmouseover="show_note(this);" onmouseout="hide_note(this);" onclick="lock_note(this);">{TEXT1}</span><span class="prime_bbcode_note_spur" onmouseover="show_note(this);" onmouseout="hide_note(this);" onclick="lock_note(this);"></span><span class="prime_bbcode_note">{TEXT2}</span>', + +				'[note={TEXT1?}]{TEXT2}[/note]', +				'<xsl:if test="@note"> +					<span class="prime_bbcode_note_text" onmouseover="show_note(this);" onmouseout="hide_note(this);" onclick="lock_note(this);"> +						<xsl:value-of select="@note"/> +					</span> +				</xsl:if> +				<span class="prime_bbcode_note_spur" onmouseover="show_note(this);" onmouseout="hide_note(this);" onclick="lock_note(this);"/> +				<span class="prime_bbcode_note"> +					<xsl:apply-templates/> +				</span>' +			], +			[ +				// https://www.phpbb.com/community/viewtopic.php?p=14768441#p14768441 +				'[MI]{TEXT}[/MI]', +				'<span style="color:red">MI:</span> <span style="color:#f6efe2">{TEXT}</span>', + +				'[MI={TEXT2}]{TEXT1}[/MI]', +				'<span style="color:red">MI for: "{TEXT2}":</span> <span style="color:#f6efe2">{TEXT1}</span>', + +				'[MI={TEXT2?}]{TEXT1}[/MI]', +				'<span style="color:red">MI<xsl:if test="@mi"> for: "<xsl:value-of select="@mi"/>"</xsl:if>:</span> +				<xsl:text> </xsl:text> +				<span style="color:#f6efe2"> +					<xsl:apply-templates/> +				</span>' +			], +			[ +				// https://www.phpbb.com/community/viewtopic.php?p=14700506#p14700506 +				'[spoiler]{TEXT}[/spoiler]', +				'<span class="spoiler"> {TEXT}</span>', + +				'[spoiler={TEXT1}]{TEXT2}[/spoiler]', +				'<div class="spoiler"><small> {TEXT1}</small>{TEXT2}</div>', + +				'[spoiler={TEXT1?}]{TEXT2}[/spoiler]', +				'<xsl:choose> +					<xsl:when test="@spoiler"> +						<div class="spoiler"> +							<small> +								<xsl:text> </xsl:text> +								<xsl:value-of select="@spoiler"/> +							</small> +							<xsl:apply-templates/> +						</div> +					</xsl:when> +					<xsl:otherwise> +						<span class="spoiler"> +							<xsl:text> </xsl:text> +							<xsl:apply-templates/> +						</span> +					</xsl:otherwise> +				</xsl:choose>' +			], +			[ +				// https://www.phpbb.com/community/viewtopic.php?p=14859676#p14859676 +				'[AE]{TEXT}[/AE]', +				'<table width="100%" border="1"> +					<tr><td width="100%" align="center"> +					<table width="100%" border="0"> +					  <tr> +						<td width="100%" bgcolor="#E1E4F2"> +						  <table width="100%" border="0" bgcolor="#F5F5FF"> +							<tr> +							  <td width="1%" bgcolor="#000000" nowrap align="left"> +								<font color="#FFFFFF" face="Arial"><font size="1"><b> ACTIVE EFFECTS & CONDITIONS </b></font></font></td> +							  <td width="99%"> </td> +							</tr> +							<tr> +							  <td width="100%" bgcolor="#FFE5BA" colspan="2"> +								<table width="100%" cellpadding="2"> +								  <tr> +									<td width="100%" align="left" valign="top"> +									  {TEXT} +									</td> +								  </tr> +								</table> +							  </td> +							</tr> +						  </table> +						</td> +					  </tr> +					</table> +				</td></tr> +				</table> +				<p> </p>', + +				'[AE={TEXT1}]{TEXT2}[/AE]', +				'<table width="100%" border="1"> +					<tr><td width="100%" align="center"> +					<table width="100%" border="0"> +					  <tr> +						<td width="100%" bgcolor="#E1E4F2"> +						  <table width="100%" border="0" bgcolor="#F5F5FF"> +							<tr> +							  <td width="1%" bgcolor="#000000" nowrap align="left"> +								<font color="#FFFFFF" face="Arial"><font size="1"><b>  {TEXT1} </b></font></font></td> +							  <td width="99%"> </td> +							</tr> +							<tr> +							  <td width="100%" bgcolor="#FFE5BA" colspan="2"> +								<table width="100%" cellpadding="2"> +								  <tr> +									<td width="100%" align="left" valign="top"> +									  {TEXT2} +									</td> +								  </tr> +								</table> +							  </td> +							</tr> +						  </table> +						</td> +					  </tr> +					</table> +					</td></tr> +				</table> +				<p> </p>', + +				'[AE={TEXT1?}]{TEXT2}[/AE]', +				'<table width="100%" border="1"> +					<tr> +						<td width="100%" align="center"> +							<table width="100%" border="0"> +								<tr> +									<td width="100%" bgcolor="#E1E4F2"> +										<table width="100%" border="0" bgcolor="#F5F5FF"> +											<tr> +												<td width="1%" bgcolor="#000000" nowrap="nowrap" align="left"> +													<font color="#FFFFFF" face="Arial"> +														<font size="1"> +															<b> <xsl:choose><xsl:when test="@ae"><xsl:text> </xsl:text><xsl:value-of select="@ae"/></xsl:when><xsl:otherwise>ACTIVE EFFECTS & CONDITIONS</xsl:otherwise></xsl:choose> </b> +														</font> +													</font> +												</td> +												<td width="99%"> </td> +											</tr> +											<tr> +												<td width="100%" bgcolor="#FFE5BA" colspan="2"> +													<table width="100%" cellpadding="2"> +														<tr> +															<td width="100%" align="left" valign="top"> +																<xsl:apply-templates/> +															</td> +														</tr> +													</table> +												</td> +											</tr> +										</table> +									</td> +								</tr> +							</table> +						</td> +					</tr> +				</table> +				<p> </p>' +			], +		]; +	} +} diff --git a/tests/text_formatter/s9e/default_formatting_test.php b/tests/text_formatter/s9e/default_formatting_test.php index a0c57214e4..8887b9daee 100644 --- a/tests/text_formatter/s9e/default_formatting_test.php +++ b/tests/text_formatter/s9e/default_formatting_test.php @@ -50,27 +50,27 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case  		return array(  			array(  				'[b]bold[/b]', -				'<span style="font-weight: bold">bold</span>' +				'<span style="font-weight:bold">bold</span>'  			),  			array(  				'[u]underlined[/u]', -				'<span style="text-decoration: underline">underlined</span>' +				'<span style="text-decoration:underline">underlined</span>'  			),  			array(  				'[i]italic[/i]', -				'<span style="font-style: italic">italic</span>' +				'<span style="font-style:italic">italic</span>'  			),  			array(  				'[color=#FF0000]colored[/color]', -				'<span style="color: #FF0000">colored</span>' +				'<span style="color:#FF0000">colored</span>'  			),  			array(  				'[color=red]colored[/color]', -				'<span style="color: red">colored</span>' +				'<span style="color:red">colored</span>'  			),  			array(  				'[size=75]smaller[/size]', -				'<span style="font-size: 75%; line-height: normal">smaller</span>' +				'<span style="font-size:75%;line-height:normal">smaller</span>'  			),  			array(  				'[quote]quoted[/quote]', @@ -102,31 +102,31 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case  			),  			array(  				'[list=1][*]item[/list]', -				'<ol style="list-style-type: decimal"><li>item</li></ol>' +				'<ol style="list-style-type:decimal"><li>item</li></ol>'  			),  			array(  				'[list=a][*]item[/list]', -				'<ol style="list-style-type: lower-alpha"><li>item</li></ol>' +				'<ol style="list-style-type:lower-alpha"><li>item</li></ol>'  			),  			array(  				'[list=i][*]item[/list]', -				'<ol style="list-style-type: lower-roman"><li>item</li></ol>' +				'<ol style="list-style-type:lower-roman"><li>item</li></ol>'  			),  			array(  				'[list=I][*]item[/list]', -				'<ol style="list-style-type: upper-roman"><li>item</li></ol>' +				'<ol style="list-style-type:upper-roman"><li>item</li></ol>'  			),  			array(  				'[list=disc][*]item[/list]', -				'<ul style="list-style-type: disc"><li>item</li></ul>' +				'<ul style="list-style-type:disc"><li>item</li></ul>'  			),  			array(  				'[list=circle][*]item[/list]', -				'<ul style="list-style-type: circle"><li>item</li></ul>' +				'<ul style="list-style-type:circle"><li>item</li></ul>'  			),  			array(  				'[list=square][*]item[/list]', -				'<ul style="list-style-type: square"><li>item</li></ul>' +				'<ul style="list-style-type:square"><li>item</li></ul>'  			),  			array(  				'[img]https://area51.phpbb.com/images/area51.png[/img]', @@ -180,17 +180,17 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case  			array(  				// Allow textual bbcodes in textual bbcodes  				'[b]bold [i]bold + italic[/i][/b]', -				'<span style="font-weight: bold">bold <span style="font-style: italic">bold + italic</span></span>' +				'<span style="font-weight:bold">bold <span style="font-style:italic">bold + italic</span></span>'  			),  			array(  				// Allow textual bbcodes in url with description  				'[url=https://area51.phpbb.com/]Area51 [i]italic[/i][/url]', -				'<a href="https://area51.phpbb.com/" class="postlink">Area51 <span style="font-style: italic">italic</span></a>' +				'<a href="https://area51.phpbb.com/" class="postlink">Area51 <span style="font-style:italic">italic</span></a>'  			),  			array(  				// Allow url with description in textual bbcodes  				'[i]italic [url=https://area51.phpbb.com/]Area51[/url][/i]', -				'<span style="font-style: italic">italic <a href="https://area51.phpbb.com/" class="postlink">Area51</a></span>' +				'<span style="font-style:italic">italic <a href="https://area51.phpbb.com/" class="postlink">Area51</a></span>'  			),  			array(  				// Do not parse textual bbcodes in code @@ -205,7 +205,7 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case  			array(  				// Textual bbcode nesting into textual bbcode  				'[b]bold [i]bold + italic[/b] italic[/i]', -				'<span style="font-weight: bold">bold <span style="font-style: italic">bold + italic</span></span><span style="font-style: italic"> italic</span>' +				'<span style="font-weight:bold">bold <span style="font-style:italic">bold + italic</span></span><span style="font-style:italic"> italic</span>'  			),  			array(  				"[code]\tline1\n  line2[/code]", @@ -298,7 +298,7 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case  			),  			array(  				"Emoji: \xF0\x9F\x98\x80", -				'Emoji: <img alt="' . "\xF0\x9F\x98\x80" . '" class="emoji smilies" draggable="false" src="//cdn.jsdelivr.net/emojione/assets/svg/1f600.svg">' +				'Emoji: <img alt="' . "\xF0\x9F\x98\x80" . '" class="emoji smilies" draggable="false" src="//cdn.jsdelivr.net/emojione/assets/3.1/png/64/1f600.png">'  			),  			array(  				"Emoji: \xF0\x9F\x98\x80", diff --git a/tests/text_formatter/s9e/factory_test.php b/tests/text_formatter/s9e/factory_test.php index fd9b4e4c09..d35330a975 100644 --- a/tests/text_formatter/s9e/factory_test.php +++ b/tests/text_formatter/s9e/factory_test.php @@ -248,6 +248,22 @@ class phpbb_textformatter_s9e_factory_test extends phpbb_database_test_case  	}  	/** +	* @testdox Accepts unsafe default BBCodes +	*/ +	public function test_unsafe_default_bbcodes() +	{ +		$fixture   = __DIR__ . '/fixtures/unsafe_default_bbcodes.xml'; +		$style_dir = __DIR__ . '/fixtures/styles/'; +		$container = $this->get_test_case_helpers()->set_s9e_services(null, $fixture, $style_dir); +		$parser    = $container->get('text_formatter.parser'); +		$renderer  = $container->get('text_formatter.renderer'); + +		$original = '[b]alert(1)[/b]'; +		$expected = '<script>alert(1)</script>'; +		$this->assertSame($expected, $renderer->render($parser->parse($original))); +	} + +	/**  	* @testdox get_configurator() triggers events before and after configuration  	*/  	public function test_configure_events() diff --git a/tests/text_formatter/s9e/fixtures/styles/unsafe/template/bbcode.html b/tests/text_formatter/s9e/fixtures/styles/unsafe/template/bbcode.html new file mode 100644 index 0000000000..f3932f9b78 --- /dev/null +++ b/tests/text_formatter/s9e/fixtures/styles/unsafe/template/bbcode.html @@ -0,0 +1,40 @@ +<!-- BEGIN ulist_open --><ul style="list-style-type: {LIST_TYPE}"><!-- END ulist_open --> +<!-- BEGIN ulist_open_default --><ul><!-- END ulist_open_default --> +<!-- BEGIN ulist_close --></ul><!-- END ulist_close --> + +<!-- BEGIN olist_open --><ol style="list-style-type: {LIST_TYPE}"><!-- END olist_open --> +<!-- BEGIN olist_close --></ol><!-- END olist_close --> + +<!-- BEGIN listitem --><li><!-- END listitem --> +<!-- BEGIN listitem_close --></li><!-- END listitem_close --> + +<!-- BEGIN quote_username_open --><blockquote><div><cite>{USERNAME} {L_WROTE}{L_COLON}</cite><!-- END quote_username_open --> +<!-- BEGIN quote_open --><blockquote class="uncited"><div><!-- END quote_open --> +<!-- BEGIN quote_close --></div></blockquote><!-- END quote_close --> + +<!-- BEGIN code_open --><div class="codebox"><p>{L_CODE}{L_COLON} <a href="#" onclick="selectCode(this); return false;">{L_SELECT_ALL_CODE}</a></p><code><!-- END code_open --> +<!-- BEGIN code_close --></code></div><!-- END code_close --> + +<!-- BEGIN inline_attachment_open --><div class="inline-attachment"><!-- END inline_attachment_open --> +<!-- BEGIN inline_attachment_close --></div><!-- END inline_attachment_close --> + +<!-- BEGIN b_open --><script><!-- END b_open --> +<!-- BEGIN b_close --></script><!-- END b_close --> + +<!-- BEGIN u_open --><span style="text-decoration: underline"><!-- END u_open --> +<!-- BEGIN u_close --></span><!-- END u_close --> + +<!-- BEGIN i_open --><em><!-- END i_open --> +<!-- BEGIN i_close --></em><!-- END i_close --> + +<!-- BEGIN color --><span style="color: {COLOR}">{TEXT}</span><!-- END color --> + +<!-- BEGIN size --><span style="font-size: {SIZE}%; line-height: 116%;">{TEXT}</span><!-- END size --> + +<!-- BEGIN img --><img src="{URL}" class="postimage" alt="{L_IMAGE}" /><!-- END img --> + +<!-- BEGIN url --><a href="{URL}" class="postlink">{DESCRIPTION}</a><!-- END url --> + +<!-- BEGIN email --><a href="mailto:{EMAIL}">{DESCRIPTION}</a><!-- END email --> + +<!-- BEGIN flash --><object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=5,0,0,0" width="{WIDTH}" height="{HEIGHT}"><param name="movie" value="{URL}" /><param name="play" value="false" /><param name="loop" value="false" /><param name="quality" value="high" /><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /><embed src="{URL}" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" width="{WIDTH}" height="{HEIGHT}" play="false" loop="false" quality="high" allowscriptaccess="never" allownetworking="internal"></embed></object><!-- END flash --> diff --git a/tests/text_formatter/s9e/fixtures/unsafe_default_bbcodes.xml b/tests/text_formatter/s9e/fixtures/unsafe_default_bbcodes.xml new file mode 100644 index 0000000000..06524a13cc --- /dev/null +++ b/tests/text_formatter/s9e/fixtures/unsafe_default_bbcodes.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_styles"> +		<column>style_id</column> +		<column>style_name</column> +		<column>style_copyright</column> +		<column>style_active</column> +		<column>style_path</column> +		<column>bbcode_bitfield</column> +		<column>style_parent_id</column> +		<column>style_parent_tree</column> + +		<row> +			<value>1</value> +			<value>unsafe</value> +			<value></value> +			<value>1</value> +			<value>unsafe</value> +			<value>QA==</value> +			<value>0</value> +			<value></value> +		</row> +	</table> +</dataset> diff --git a/tests/text_processing/tickets_data/PHPBB3-10122.html b/tests/text_processing/tickets_data/PHPBB3-10122.html index f0fb6115b2..0803c895a8 100644 --- a/tests/text_processing/tickets_data/PHPBB3-10122.html +++ b/tests/text_processing/tickets_data/PHPBB3-10122.html @@ -1 +1 @@ -<ul style="list-style-type: none"><li>This is my indented text</li></ul>
\ No newline at end of file +<ul style="list-style-type:none"><li>This is my indented text</li></ul>
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-10268.html b/tests/text_processing/tickets_data/PHPBB3-10268.html index c89e63f9a3..13b71b4823 100644 --- a/tests/text_processing/tickets_data/PHPBB3-10268.html +++ b/tests/text_processing/tickets_data/PHPBB3-10268.html @@ -1,4 +1,4 @@  <blockquote><div><cite><a href="http://phpbb.com" class="postlink">http://phpbb.com</a> wrote:</cite>...</div></blockquote>  <blockquote><div><cite><a href="http://phpbb.com" class="postlink"> http://phpbb.com</a> wrote:</cite>...</div></blockquote> -<span style="font-weight: bold"><a href="http://phpbb.com" class="postlink">http://phpbb.com</a></span><br> -<span style="font-weight: bold"> <a href="http://phpbb.com" class="postlink">http://phpbb.com</a></span><br> +<span style="font-weight:bold"><a href="http://phpbb.com" class="postlink">http://phpbb.com</a></span><br> +<span style="font-weight:bold"> <a href="http://phpbb.com" class="postlink">http://phpbb.com</a></span><br> diff --git a/tests/text_processing/tickets_data/PHPBB3-13641.html b/tests/text_processing/tickets_data/PHPBB3-13641.html index 1bd1c06dbb..2646bc0ea5 100644 --- a/tests/text_processing/tickets_data/PHPBB3-13641.html +++ b/tests/text_processing/tickets_data/PHPBB3-13641.html @@ -1 +1 @@ -<code>[color=#FF0000]</code> - <span style="color: #FF0000">red</span>
\ No newline at end of file +<code>[color=#FF0000]</code> - <span style="color:#FF0000">red</span>
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-13921.html b/tests/text_processing/tickets_data/PHPBB3-13921.html index 6a9dc7f504..690668ef28 100644 --- a/tests/text_processing/tickets_data/PHPBB3-13921.html +++ b/tests/text_processing/tickets_data/PHPBB3-13921.html @@ -1 +1 @@ -<span style="font-size: 200%; line-height: normal"></span><div style="text-align:center"><span style="font-size: 200%; line-height: normal">xxx</span></div>
\ No newline at end of file +<span style="font-size:200%;line-height:normal"></span><div style="text-align:center"><span style="font-size:200%;line-height:normal">xxx</span></div>
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-14706.html b/tests/text_processing/tickets_data/PHPBB3-14706.html index b8f74c9e93..23b3304485 100644 --- a/tests/text_processing/tickets_data/PHPBB3-14706.html +++ b/tests/text_processing/tickets_data/PHPBB3-14706.html @@ -1 +1 @@ -<ul><li><ol style="list-style-type: lower-alpha"><li>a</li><li>b</li><li>c</li><li>d</li><li>e</li></ol></li><li>outer</li></ul>
\ No newline at end of file +<ul><li><ol style="list-style-type:lower-alpha"><li>a</li><li>b</li><li>c</li><li>d</li><li>e</li></ol></li><li>outer</li></ul>
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-14790.html b/tests/text_processing/tickets_data/PHPBB3-14790.html index 7624b2d36c..5384098e1b 100644 --- a/tests/text_processing/tickets_data/PHPBB3-14790.html +++ b/tests/text_processing/tickets_data/PHPBB3-14790.html @@ -1,4 +1,4 @@ -<span style="color: #0000FF"></span><ul><li><span style="color: #0000FF">text</span></li> -<li><span style="color: #0000FF">text</span></li> -<li><span style="color: #0000FF">text</span></li> -<li><span style="color: #0000FF">text</span></li></ul>
\ No newline at end of file +<span style="color:#0000FF"></span><ul><li><span style="color:#0000FF">text</span></li> +<li><span style="color:#0000FF">text</span></li> +<li><span style="color:#0000FF">text</span></li> +<li><span style="color:#0000FF">text</span></li></ul>
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-14846.html b/tests/text_processing/tickets_data/PHPBB3-14846.html index 461ca25bc6..bd4455781b 100644 --- a/tests/text_processing/tickets_data/PHPBB3-14846.html +++ b/tests/text_processing/tickets_data/PHPBB3-14846.html @@ -1 +1 @@ -<div style="padding: .2em .5em; font-size: .8em; width: 200px; background: #FFD;">moderator text<div style="font-weight: bold; text-align: right">- Mickroz</div></div>
\ No newline at end of file +<div style="padding:.2em .5em;font-size:.8em;width:200px;background:#ffd">moderator text<div style="font-weight:bold;text-align:right">- Mickroz</div></div>
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-15348.html b/tests/text_processing/tickets_data/PHPBB3-15348.html index e65925ec28..5d44c07899 100644 --- a/tests/text_processing/tickets_data/PHPBB3-15348.html +++ b/tests/text_processing/tickets_data/PHPBB3-15348.html @@ -1 +1 @@ -<img class="smilies" src="phpBB/images/smilies/icon_e_surprised.gif" width="15" height="17" alt=":o" title="First half of :ok:"> <img class="smilies" src="phpBB/images/smilies/icon_lol.gif" width="15" height="17" alt="k:" title="Second half of :ok:"> <img alt=":ok:" class="emoji smilies" draggable="false" src="//cdn.jsdelivr.net/emojione/assets/svg/1f197.svg">
\ No newline at end of file +<img class="smilies" src="phpBB/images/smilies/icon_e_surprised.gif" width="15" height="17" alt=":o" title="First half of :ok:"> <img class="smilies" src="phpBB/images/smilies/icon_lol.gif" width="15" height="17" alt="k:" title="Second half of :ok:"> <img alt=":ok:" class="emoji smilies" draggable="false" src="//cdn.jsdelivr.net/emojione/assets/3.1/png/64/1f197.png">
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-8419.html b/tests/text_processing/tickets_data/PHPBB3-8419.html index 38df626a94..df91e9df50 100644 --- a/tests/text_processing/tickets_data/PHPBB3-8419.html +++ b/tests/text_processing/tickets_data/PHPBB3-8419.html @@ -1 +1 @@ -<span style="font-style: italic"><span style="font-weight: bold"><span style="color: #FF0000">tę </span></span></span>przykład
\ No newline at end of file +<span style="font-style:italic"><span style="font-weight:bold"><span style="color:red">tę </span></span></span>przykład
\ No newline at end of file diff --git a/tests/text_reparser/base_test.php b/tests/text_reparser/base_test.php index af2d56ea51..2c6844b063 100644 --- a/tests/text_reparser/base_test.php +++ b/tests/text_reparser/base_test.php @@ -66,4 +66,19 @@ class phpbb_textreparser_base_test extends phpbb_database_test_case  			$this->get_rows(array(1))  		);  	} + +	public function test_reparse_case_insensitive() +	{ +		$this->get_reparser()->reparse_range(2, 2); + +		$this->assertEquals( +			[ +				[ +					'id'   => '2', +					'text' => '<r><IMG src="img.png"><s>[IMG]</s>img.png<e>[/IMG]</e></IMG></r>' +				] +			], +			$this->get_rows([2]) +		); +	}  } diff --git a/tests/text_reparser/fixtures/base.xml b/tests/text_reparser/fixtures/base.xml index a4921a8823..532a19a8a9 100644 --- a/tests/text_reparser/fixtures/base.xml +++ b/tests/text_reparser/fixtures/base.xml @@ -15,5 +15,13 @@  			<value></value>  			<value>abcd1234</value>  		</row> +		<row> +			<value>2</value> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value><![CDATA[<r><IMG src="img.png"><s>[IMG]</s>img.png<e>[/IMG]</e></IMG></r>]]></value> +			<value></value> +		</row>  	</table>  </dataset> | 
