diff options
186 files changed, 1978 insertions, 632 deletions
| diff --git a/build/build.xml b/build/build.xml index 615e420a13..dd5fa4c5d8 100644 --- a/build/build.xml +++ b/build/build.xml @@ -2,9 +2,9 @@  <project name="phpBB" description="The phpBB forum software" default="all" basedir="../">  	<!-- a few settings for the build --> -	<property name="newversion" value="3.2.0-RC3-dev" /> -	<property name="prevversion" value="3.2.0-RC2" /> -	<property name="olderversions" value="3.0.14, 3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.2.0-a1, 3.2.0-a2, 3.2.0-b1, 3.2.0-b2, 3.2.0-RC1" /> +	<property name="newversion" value="3.2.1-dev" /> +	<property name="prevversion" value="3.2.0" /> +	<property name="olderversions" value="3.0.14, 3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.2.0-a1, 3.2.0-a2, 3.2.0-b1, 3.2.0-b2, 3.2.0-RC1, 3.2.0-RC2" />  	<!-- no configuration should be needed beyond this point -->  	<property name="oldversions" value="${olderversions}, ${prevversion}" /> diff --git a/git-tools/setup_github_network.php b/git-tools/setup_github_network.php deleted file mode 100755 index 100ac53b33..0000000000 --- a/git-tools/setup_github_network.php +++ /dev/null @@ -1,292 +0,0 @@ -#!/usr/bin/env php -<?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. -* -*/ - -function show_usage() -{ -	$filename = basename(__FILE__); - -	echo "$filename adds repositories of a github network as remotes to a local git repository.\n"; -	echo "\n"; - -	echo "Usage: [php] $filename -s collaborators|organisation|contributors|forks [OPTIONS]\n"; -	echo "\n"; - -	echo "Scopes:\n"; -	echo "  collaborators                 Repositories of people who have push access to the specified repository\n"; -	echo "  contributors                  Repositories of people who have contributed to the specified repository\n"; -	echo "  organisation                  Repositories of members of the organisation at github\n"; -	echo "  forks                         All repositories of the whole github network\n"; -	echo "\n"; - -	echo "Options:\n"; -	echo " -s scope                       See description above (mandatory)\n"; -	echo " -u github_username             Overwrites the github username (optional)\n"; -	echo " -r repository_name             Overwrites the repository name (optional)\n"; -	echo " -m your_github_username        Sets up ssh:// instead of git:// for pushable repositories (optional)\n"; -	echo " -d                             Outputs the commands instead of running them (optional)\n"; -	echo " -h                             This help text\n"; - -	exit(1); -} - -// Handle arguments -$opts = getopt('s:u:r:m:dh'); - -if (empty($opts) || isset($opts['h'])) -{ -	show_usage(); -} - -$scope			= get_arg($opts, 's', ''); -$username		= get_arg($opts, 'u', 'phpbb'); -$repository 	= get_arg($opts, 'r', 'phpbb3'); -$developer		= get_arg($opts, 'm', ''); -$dry_run		= !get_arg($opts, 'd', true); -run(null, $dry_run); -exit(work($scope, $username, $repository, $developer)); - -function work($scope, $username, $repository, $developer) -{ -	// Get some basic data -	$forks		= get_forks($username, $repository); -	$collaborators	= get_collaborators($username, $repository); - -	if ($forks === false || $collaborators === false) -	{ -		echo "Error: failed to retrieve forks or collaborators\n"; -		return 1; -	} - -	switch ($scope) -	{ -		case 'collaborators': -			$remotes = array_intersect_key($forks, $collaborators); -		break; - -		case 'organisation': -			$remotes = array_intersect_key($forks, get_organisation_members($username)); -		break; - -		case 'contributors': -			$remotes = array_intersect_key($forks, get_contributors($username, $repository)); -		break; - -		case 'forks': -			$remotes = $forks; -		break; - -		default: -			show_usage(); -	} - -	if (file_exists('.git')) -	{ -		add_remote($username, $repository, isset($collaborators[$developer])); -	} -	else -	{ -		clone_repository($username, $repository, isset($collaborators[$developer])); -	} - -	// Add private security repository for developers -	if ($username == 'phpbb' && $repository == 'phpbb3' && isset($collaborators[$developer])) -	{ -		run("git remote add $username-security " . get_repository_url($username, "$repository-security", true)); -	} - -	// Skip blessed repository. -	unset($remotes[$username]); - -	foreach ($remotes as $remote) -	{ -		add_remote($remote['username'], $remote['repository'], $remote['username'] == $developer); -	} - -	run('git remote update'); -} - -function clone_repository($username, $repository, $pushable = false) -{ -	$url = get_repository_url($username, $repository, false); -	run("git clone $url ./ --origin $username"); - -	if ($pushable) -	{ -		$ssh_url = get_repository_url($username, $repository, true); -		run("git remote set-url --push $username $ssh_url"); -	} -} - -function add_remote($username, $repository, $pushable = false) -{ -	$url = get_repository_url($username, $repository, false); -	run("git remote add $username $url"); - -	if ($pushable) -	{ -		$ssh_url = get_repository_url($username, $repository, true); -		run("git remote set-url --push $username $ssh_url"); -	} -} - -function get_repository_url($username, $repository, $ssh = false) -{ -	$url_base = ($ssh) ? 'git@github.com:' : 'git://github.com/'; - -	return $url_base . $username . '/' . $repository . '.git'; -} - -function api_request($query) -{ -	return api_url_request("https://api.github.com/$query?per_page=100"); -} - -function api_url_request($url) -{ -	$contents = file_get_contents($url, false, stream_context_create(array( -		'http' => array( -			'header' => "User-Agent: phpBB/1.0\r\n", -		), -	))); - -	$sub_request_result = array(); -	// Check headers for pagination links -	if (!empty($http_response_header)) -	{ -		foreach ($http_response_header as $header_element) -		{ -			// Find Link Header which gives us a link to the next page -			if (strpos($header_element, 'Link: ') === 0) -			{ -				list($head, $header_content) = explode(': ', $header_element); -				foreach (explode(', ', $header_content) as $links) -				{ -					list($url, $rel) = explode('; ', $links); -					if ($rel == 'rel="next"') -					{ -						// Found a next link, follow it and merge the results -						$sub_request_result = api_url_request(substr($url, 1, -1)); -					} -				} -			} -		} -	} - -	if ($contents === false) -	{ -		return false; -	} -	$contents = json_decode($contents); - -	if (isset($contents->message) && strpos($contents->message, 'API Rate Limit') === 0) -	{ -		throw new RuntimeException('Reached github API Rate Limit. Please try again later' . "\n", 4); -	} - -	return ($sub_request_result) ? array_merge($sub_request_result, $contents) : $contents; -} - -function get_contributors($username, $repository) -{ -	$request = api_request("repos/$username/$repository/stats/contributors"); -	if ($request === false) -	{ -		return false; -	} - -	$usernames = array(); -	foreach ($request as $contribution) -	{ -		$usernames[$contribution->author->login] = $contribution->author->login; -	} - -	return $usernames; -} - -function get_organisation_members($username) -{ -	$request = api_request("orgs/$username/public_members"); -	if ($request === false) -	{ -		return false; -	} - -	$usernames = array(); -	foreach ($request as $member) -	{ -		$usernames[$member->login] = $member->login; -	} - -	return $usernames; -} - -function get_collaborators($username, $repository) -{ -	$request = api_request("repos/$username/$repository/collaborators"); -	if ($request === false) -	{ -		return false; -	} - -	$usernames = array(); -	foreach ($request as $collaborator) -	{ -		$usernames[$collaborator->login] = $collaborator->login; -	} - -	return $usernames; -} - -function get_forks($username, $repository) -{ -	$request = api_request("repos/$username/$repository/forks"); -	if ($request === false) -	{ -		return false; -	} - -	$usernames = array(); -	foreach ($request as $fork) -	{ -		$usernames[$fork->owner->login] = array( -			'username'		=> $fork->owner->login, -			'repository'	=> $fork->name, -		); -	} - -	return $usernames; -} - -function get_arg($array, $index, $default) -{ -	return isset($array[$index]) ? $array[$index] : $default; -} - -function run($cmd, $dry = false) -{ -	static $dry_run; - -	if (is_null($cmd)) -	{ -		$dry_run = $dry; -	} -	else if (!empty($dry_run)) -	{ -		echo "$cmd\n"; -	} -	else -	{ -		passthru(escapeshellcmd($cmd)); -	} -} diff --git a/phpBB/adm/style/acp_ext_details.html b/phpBB/adm/style/acp_ext_details.html index 4c1feb59a9..d7839f7ec8 100644 --- a/phpBB/adm/style/acp_ext_details.html +++ b/phpBB/adm/style/acp_ext_details.html @@ -134,4 +134,5 @@  		<!-- END meta_authors -->  	</fieldset> +	<!-- EVENT acp_ext_details_end -->  <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html index ccc39ea76d..af9e00a614 100644 --- a/phpBB/adm/style/acp_ext_list.html +++ b/phpBB/adm/style/acp_ext_list.html @@ -48,7 +48,7 @@  		</tr>  		<!-- BEGIN enabled -->  		<tr class="ext_enabled row-highlight"> -			<td><strong title="{enabled.NAME}">{enabled.META_DISPLAY_NAME}</strong></td> +			<td><strong title="{enabled.NAME}">{enabled.META_DISPLAY_NAME}</strong><!-- EVENT acp_ext_list_enabled_name_after --></td>  			<td style="text-align: center;">  				<!-- IF enabled.S_VERSIONCHECK -->  				<strong <!-- IF enabled.S_UP_TO_DATE -->style="color: #228822;"<!-- ELSE -->style="color: #BC2A4D;"<!-- ENDIF -->>{enabled.META_VERSION}</strong> @@ -73,7 +73,7 @@  		</tr>  		<!-- BEGIN disabled -->  		<tr class="ext_disabled row-highlight"> -			<td><strong title="{disabled.NAME}">{disabled.META_DISPLAY_NAME}</strong></td> +			<td><strong title="{disabled.NAME}">{disabled.META_DISPLAY_NAME}</strong><!-- EVENT acp_ext_list_disabled_name_after --></td>  			<td style="text-align: center;">  				<!-- IF disabled.S_VERSIONCHECK -->  				<strong <!-- IF disabled.S_UP_TO_DATE -->style="color: #228822;"<!-- ELSE -->style="color: #BC2A4D;"<!-- ENDIF -->>{disabled.META_VERSION}</strong> diff --git a/phpBB/adm/style/acp_main.html b/phpBB/adm/style/acp_main.html index efcb25cb68..1bdb7b8d2a 100644 --- a/phpBB/adm/style/acp_main.html +++ b/phpBB/adm/style/acp_main.html @@ -30,6 +30,11 @@  			<p><a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a> · <a href="{U_VERSIONCHECK}">{L_MORE_INFORMATION}</a></p>  		</div>  	<!-- ENDIF --> +	<!-- IF S_VERSION_UPGRADEABLE --> +		<div class="errorbox notice"> +			<p>{UPGRADE_INSTRUCTIONS}</p> +		</div> +	<!-- ENDIF -->  	<!-- IF S_SEARCH_INDEX_MISSING -->  		<div class="errorbox"> diff --git a/phpBB/adm/style/acp_update.html b/phpBB/adm/style/acp_update.html index 351a3ba26c..5288833d05 100644 --- a/phpBB/adm/style/acp_update.html +++ b/phpBB/adm/style/acp_update.html @@ -20,6 +20,11 @@  		<p>{L_VERSION_NOT_UP_TO_DATE_ACP} - <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a></p>  	</div>  <!-- ENDIF --> +<!-- IF S_VERSION_UPGRADEABLE --> +	<div class="errorbox notice"> +		<p>{UPGRADE_INSTRUCTIONS}</p> +	</div> +<!-- ENDIF -->  <fieldset>  	<legend></legend> diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index bcf01fe597..d46530700f 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -1,4 +1,4 @@ -/*  phpBB 3.1 Admin Style Sheet +/*  phpBB 3.2 Admin Style Sheet  	------------------------------------------------------------------------  	Original author:	subBlue ( http://www.subblue.com/ )  	Copyright (c) phpBB Limited <https://www.phpbb.com> diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index 6f94048d05..895bb056e5 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -280,10 +280,11 @@ function submitPermissions() {  		$.ajax({  			url: $form.action,  			type: 'POST', -			data: formData + '&' + $submitAllButton.name + '=' + encodeURIComponent($submitAllButton.value) + +			data: formData + '&' + $submitButton.name + '=' + encodeURIComponent($submitButton.value) +  				'&creation_time=' + $form.find('input[type=hidden][name=creation_time]')[0].value +  				'&form_token=' + $form.find('input[type=hidden][name=form_token]')[0].value + -				'&' + $form.children('input[type=hidden]').serialize(), +				'&' + $form.children('input[type=hidden]').serialize() + +				'&' + $form.find('input[type=checkbox][name^=inherit]').serialize(),  			success: handlePermissionReturn,  			error: handlePermissionReturn  		}); diff --git a/phpBB/adm/style/overall_header.html b/phpBB/adm/style/overall_header.html index 1e8de766ff..8279ac34dc 100644 --- a/phpBB/adm/style/overall_header.html +++ b/phpBB/adm/style/overall_header.html @@ -54,7 +54,7 @@ function marklist(id, name, state)  	for (var r = 0; r < rb.length; r++)  	{ -		if (rb[r].name.substr(0, name.length) == name) +		if (rb[r].name.substr(0, name.length) == name && rb[r].disabled !== true)  		{  			rb[r].checked = state;  		} diff --git a/phpBB/adm/style/simple_header.html b/phpBB/adm/style/simple_header.html index 9f47b2052b..439645a211 100644 --- a/phpBB/adm/style/simple_header.html +++ b/phpBB/adm/style/simple_header.html @@ -66,7 +66,7 @@ function marklist(id, name, state)  	for (var r = 0; r < rb.length; r++)  	{ -		if (rb[r].name.substr(0, name.length) == name) +		if (rb[r].name.substr(0, name.length) == name && rb[r].disabled !== true)  		{  			rb[r].checked = state;  		} diff --git a/phpBB/assets/cookieconsent/cookieconsent.min.css b/phpBB/assets/cookieconsent/cookieconsent.min.css new file mode 100644 index 0000000000..03c69fe82f --- /dev/null +++ b/phpBB/assets/cookieconsent/cookieconsent.min.css @@ -0,0 +1,6 @@ +.cc-window{opacity:1;transition:opacity 1s ease}.cc-window.cc-invisible{opacity:0}.cc-animate.cc-revoke{transition:transform 1s ease}.cc-animate.cc-revoke.cc-top{transform:translateY(-2em)}.cc-animate.cc-revoke.cc-bottom{transform:translateY(2em)}.cc-animate.cc-revoke.cc-active.cc-bottom,.cc-animate.cc-revoke.cc-active.cc-top,.cc-revoke:hover{transform:translateY(0)}.cc-grower{max-height:0;overflow:hidden;transition:max-height 1s} +.cc-link,.cc-revoke:hover{text-decoration:underline}.cc-revoke,.cc-window{position:fixed;overflow:hidden;box-sizing:border-box;font-family:Helvetica,Calibri,Arial,sans-serif;font-size:16px;line-height:1.5em;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;z-index:9999}.cc-window.cc-static{position:static}.cc-window.cc-floating{padding:2em;max-width:24em;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner{padding:1em 1.8em;width:100%;-ms-flex-direction:row;flex-direction:row}.cc-revoke{padding:.5em}.cc-header{font-size:18px;font-weight:700}.cc-btn,.cc-close,.cc-link,.cc-revoke{cursor:pointer}.cc-link{opacity:.8;display:inline-block;padding:.2em}.cc-link:hover{opacity:1}.cc-link:active,.cc-link:visited{color:initial}.cc-btn{display:block;padding:.4em .8em;font-size:.9em;font-weight:700;border-width:2px;border-style:solid;text-align:center;white-space:nowrap}.cc-banner .cc-btn:last-child{min-width:140px}.cc-highlight .cc-btn:first-child{background-color:transparent;border-color:transparent}.cc-highlight .cc-btn:first-child:focus,.cc-highlight .cc-btn:first-child:hover{background-color:transparent;text-decoration:underline}.cc-close{display:block;position:absolute;top:.5em;right:.5em;font-size:1.6em;opacity:.9;line-height:.75}.cc-close:focus,.cc-close:hover{opacity:1} +.cc-revoke.cc-top{top:0;left:3em;border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}.cc-revoke.cc-bottom{bottom:0;left:3em;border-top-left-radius:.5em;border-top-right-radius:.5em}.cc-revoke.cc-left{left:3em;right:unset}.cc-revoke.cc-right{right:3em;left:unset}.cc-top{top:1em}.cc-left{left:1em}.cc-right{right:1em}.cc-bottom{bottom:1em}.cc-floating>.cc-link{margin-bottom:1em}.cc-floating .cc-message{display:block;margin-bottom:1em}.cc-window.cc-floating .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-banner{-ms-flex-align:center;align-items:center}.cc-banner.cc-top{left:0;right:0;top:0}.cc-banner.cc-bottom{left:0;right:0;bottom:0}.cc-banner .cc-message{-ms-flex:1;flex:1}.cc-compliance{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:justify;align-content:space-between}.cc-compliance>.cc-btn{-ms-flex:1;flex:1}.cc-btn+.cc-btn{margin-left:.5em} +@media print{.cc-revoke,.cc-window{display:none}}@media screen and (max-width:900px){.cc-btn{white-space:normal}}@media screen and (max-width:414px) and (orientation:portrait),screen and (max-width:736px) and (orientation:landscape){.cc-window.cc-top{top:0}.cc-window.cc-bottom{bottom:0}.cc-window.cc-banner,.cc-window.cc-left,.cc-window.cc-right{left:0;right:0}.cc-window.cc-banner{-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-floating{max-width:none}.cc-window .cc-message{margin-bottom:1em}.cc-window.cc-banner{-ms-flex-align:unset;align-items:unset}} +.cc-floating.cc-theme-classic{padding:1.2em;border-radius:5px}.cc-floating.cc-type-info.cc-theme-classic .cc-compliance{text-align:center;display:inline;-ms-flex:none;flex:none}.cc-theme-classic .cc-btn{border-radius:5px}.cc-theme-classic .cc-btn:last-child{min-width:140px}.cc-floating.cc-type-info.cc-theme-classic .cc-btn{display:inline-block} +.cc-theme-edgeless.cc-window{padding:0}.cc-floating.cc-theme-edgeless .cc-message{margin:2em 2em 1.5em}.cc-banner.cc-theme-edgeless .cc-btn{margin:0;padding:.8em 1.8em;height:100%}.cc-banner.cc-theme-edgeless .cc-message{margin-left:1em}.cc-floating.cc-theme-edgeless .cc-btn+.cc-btn{margin-left:0}
\ No newline at end of file diff --git a/phpBB/assets/cookieconsent/cookieconsent.min.js b/phpBB/assets/cookieconsent/cookieconsent.min.js new file mode 100644 index 0000000000..8e44bdde90 --- /dev/null +++ b/phpBB/assets/cookieconsent/cookieconsent.min.js @@ -0,0 +1 @@ +!function(e){if(!e.hasInitialised){var t={escapeRegExp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},hasClass:function(e,t){var i=" ";return 1===e.nodeType&&(i+e.className+i).replace(/[\n\t]/g,i).indexOf(i+t+i)>=0},addClass:function(e,t){e.className+=" "+t},removeClass:function(e,t){var i=new RegExp("\\b"+this.escapeRegExp(t)+"\\b");e.className=e.className.replace(i,"")},interpolateString:function(e,t){var i=/{{([a-z][a-z0-9\-_]*)}}/gi;return e.replace(i,function(e){return t(arguments[1])||""})},getCookie:function(e){var t="; "+document.cookie,i=t.split("; "+e+"=");return 2!=i.length?void 0:i.pop().split(";").shift()},setCookie:function(e,t,i,n,o){var s=new Date;s.setDate(s.getDate()+(i||365));var r=[e+"="+t,"expires="+s.toUTCString(),"path="+(o||"/")];n&&r.push("domain="+n),document.cookie=r.join(";")},deepExtend:function(e,t){for(var i in t)t.hasOwnProperty(i)&&(i in e&&this.isPlainObject(e[i])&&this.isPlainObject(t[i])?this.deepExtend(e[i],t[i]):e[i]=t[i]);return e},throttle:function(e,t){var i=!1;return function(){i||(e.apply(this,arguments),i=!0,setTimeout(function(){i=!1},t))}},hash:function(e){var t,i,n,o=0;if(0===e.length)return o;for(t=0,n=e.length;t<n;++t)i=e.charCodeAt(t),o=(o<<5)-o+i,o|=0;return o},normaliseHex:function(e){return"#"==e[0]&&(e=e.substr(1)),3==e.length&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),e},getContrast:function(e){e=this.normaliseHex(e);var t=parseInt(e.substr(0,2),16),i=parseInt(e.substr(2,2),16),n=parseInt(e.substr(4,2),16),o=(299*t+587*i+114*n)/1e3;return o>=128?"#000":"#fff"},getLuminance:function(e){var t=parseInt(this.normaliseHex(e),16),i=38,n=(t>>16)+i,o=(t>>8&255)+i,s=(255&t)+i,r=(16777216+65536*(n<255?n<1?0:n:255)+256*(o<255?o<1?0:o:255)+(s<255?s<1?0:s:255)).toString(16).slice(1);return"#"+r},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object}};e.status={deny:"deny",allow:"allow",dismiss:"dismiss"},e.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var i in t)if(t.hasOwnProperty(i)&&"undefined"!=typeof e.style[i+"ransition"])return t[i];return""}(),e.hasTransition=!!e.transitionEnd;var i=Object.keys(e.status).map(t.escapeRegExp);e.customStyles={},e.Popup=function(){function n(){this.initialise.apply(this,arguments)}function o(e){this.openingTimeout=null,t.removeClass(e,"cc-invisible")}function s(t){t.style.display="none",t.removeEventListener(e.transitionEnd,this.afterTransition),this.afterTransition=null}function r(){var t=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return t(e.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return t(e.status.allow),!0;var i=Object.keys(e.status),n=this.getStatus(),o=i.indexOf(n)>=0;return o&&t(n),o}function a(){var e=this.options.position.split("-"),t=[];return e.forEach(function(e){t.push("cc-"+e)}),t}function c(){var e=this.options,i="top"==e.position||"bottom"==e.position?"banner":"floating";t.isMobile()&&(i="floating");var n=["cc-"+i,"cc-type-"+e.type,"cc-theme-"+e.theme];e["static"]&&n.push("cc-static"),n.push.apply(n,a.call(this));p.call(this,this.options.palette);return this.customStyleSelector&&n.push(this.customStyleSelector),n}function l(){var e={},i=this.options;i.showLink||(i.elements.link="",i.elements.messagelink=i.elements.message),Object.keys(i.elements).forEach(function(n){e[n]=t.interpolateString(i.elements[n],function(e){var t=i.content[e];return e&&"string"==typeof t&&t.length?t:""})});var n=i.compliance[i.type];n||(n=i.compliance.info),e.compliance=t.interpolateString(n,function(t){return e[t]});var o=i.layouts[i.layout];return o||(o=i.layouts.basic),t.interpolateString(o,function(t){return e[t]})}function u(i){var n=this.options,o=document.createElement("div"),s=n.container&&1===n.container.nodeType?n.container:document.body;o.innerHTML=i;var r=o.children[0];return r.style.display="none",t.hasClass(r,"cc-window")&&e.hasTransition&&t.addClass(r,"cc-invisible"),this.onButtonClick=h.bind(this),r.addEventListener("click",this.onButtonClick),n.autoAttach&&(s.firstChild?s.insertBefore(r,s.firstChild):s.appendChild(r)),r}function h(n){var o=n.target;if(t.hasClass(o,"cc-btn")){var s=o.className.match(new RegExp("\\bcc-("+i.join("|")+")\\b")),r=s&&s[1]||!1;r&&(this.setStatus(r),this.close(!0))}t.hasClass(o,"cc-close")&&(this.setStatus(e.status.dismiss),this.close(!0)),t.hasClass(o,"cc-revoke")&&this.revokeChoice()}function p(e){var i=t.hash(JSON.stringify(e)),n="cc-color-override-"+i,o=t.isPlainObject(e);return this.customStyleSelector=o?n:null,o&&d(i,e,"."+n),o}function d(i,n,o){if(e.customStyles[i])return void++e.customStyles[i].references;var s={},r=n.popup,a=n.button,c=n.highlight;r&&(r.text=r.text?r.text:t.getContrast(r.background),r.link=r.link?r.link:r.text,s[o+".cc-window"]=["color: "+r.text,"background-color: "+r.background],s[o+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],s[o+" .cc-link,"+o+" .cc-link:active,"+o+" .cc-link:visited"]=["color: "+r.link],a&&(a.text=a.text?a.text:t.getContrast(a.background),a.border=a.border?a.border:"transparent",s[o+" .cc-btn"]=["color: "+a.text,"border-color: "+a.border,"background-color: "+a.background],"transparent"!=a.background&&(s[o+" .cc-btn:hover, "+o+" .cc-btn:focus"]=["background-color: "+v(a.background)]),c?(c.text=c.text?c.text:t.getContrast(c.background),c.border=c.border?c.border:"transparent",s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+c.text,"border-color: "+c.border,"background-color: "+c.background]):s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var l=document.createElement("style");document.head.appendChild(l),e.customStyles[i]={references:1,element:l.sheet};var u=-1;for(var h in s)s.hasOwnProperty(h)&&l.sheet.insertRule(h+"{"+s[h].join(";")+"}",++u)}function v(e){return e=t.normaliseHex(e),"000000"==e?"#222":t.getLuminance(e)}function f(i){if(t.isPlainObject(i)){var n=t.hash(JSON.stringify(i)),o=e.customStyles[n];if(o&&!--o.references){var s=o.element.ownerNode;s&&s.parentNode&&s.parentNode.removeChild(s),e.customStyles[n]=null}}}function m(e,t){for(var i=0,n=e.length;i<n;++i){var o=e[i];if(o instanceof RegExp&&o.test(t)||"string"==typeof o&&o.length&&o===t)return!0}return!1}function b(){var t=this.setStatus.bind(this),i=this.options.dismissOnTimeout;"number"==typeof i&&i>=0&&(this.dismissTimeout=window.setTimeout(function(){t(e.status.dismiss)},Math.floor(i)));var n=this.options.dismissOnScroll;if("number"==typeof n&&n>=0){var o=function(i){window.pageYOffset>Math.floor(n)&&(t(e.status.dismiss),window.removeEventListener("scroll",o),this.onWindowScroll=null)};this.onWindowScroll=o,window.addEventListener("scroll",o)}}function y(){if("info"!=this.options.type&&(this.options.revokable=!0),t.isMobile()&&(this.options.animateRevokable=!1),this.options.revokable){var e=a.call(this);this.options.animateRevokable&&e.push("cc-animate"),this.customStyleSelector&&e.push(this.customStyleSelector);var i=this.options.revokeBtn.replace("{{classes}}",e.join(" "));this.revokeBtn=u.call(this,i);var n=this.revokeBtn;if(this.options.animateRevokable){var o=t.throttle(function(e){var i=!1,o=20,s=window.innerHeight-20;t.hasClass(n,"cc-top")&&e.clientY<o&&(i=!0),t.hasClass(n,"cc-bottom")&&e.clientY>s&&(i=!0),i?t.hasClass(n,"cc-active")||t.addClass(n,"cc-active"):t.hasClass(n,"cc-active")&&t.removeClass(n,"cc-active")},200);this.onMouseMove=o,window.addEventListener("mousemove",o)}}}var g={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"http://cookiesandyou.com",close:"❌"},elements:{header:'<span class="cc-header">{{header}}</span> ',message:'<span id="cookieconsent:desc" class="cc-message">{{message}}</span>',messagelink:'<span id="cookieconsent:desc" class="cc-message">{{message}} <a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" target="_blank">{{link}}</a></span>',dismiss:'<a aria-label="dismiss cookie message" role=button tabindex="0" class="cc-btn cc-dismiss">{{dismiss}}</a>',allow:'<a aria-label="allow cookies" role=button tabindex="0"  class="cc-btn cc-allow">{{allow}}</a>',deny:'<a aria-label="deny cookies" role=button tabindex="0" class="cc-btn cc-deny">{{deny}}</a>',link:'<a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" target="_blank">{{link}}</a>',close:'<span aria-label="dismiss cookie message" role=button tabindex="0" class="cc-close">{{close}}</span>'},window:'<div role="dialog" aria-live="polite" aria-label="cookieconsent" aria-describedby="cookieconsent:desc" class="cc-window {{classes}}"><!--googleoff: all-->{{children}}<!--googleon: all--></div>',revokeBtn:'<div class="cc-revoke {{classes}}">Cookie Policy</div>',compliance:{info:'<div class="cc-compliance">{{dismiss}}</div>',"opt-in":'<div class="cc-compliance cc-highlight">{{dismiss}}{{allow}}</div>',"opt-out":'<div class="cc-compliance cc-highlight">{{deny}}{{dismiss}}</div>'},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block","static":!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null};return n.prototype.initialise=function(e){this.options&&this.destroy(),t.deepExtend(this.options={},g),t.isPlainObject(e)&&t.deepExtend(this.options,e),r.call(this)&&(this.options.enabled=!1),m(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),m(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var i=this.options.window.replace("{{classes}}",c.call(this).join(" ")).replace("{{children}}",l.call(this)),n=this.options.overrideHTML;if("string"==typeof n&&n.length&&(i=n),this.options["static"]){var o=u.call(this,'<div class="cc-grower">'+i+"</div>");o.style.display="",this.element=o.firstChild,this.element.style.display="none",t.addClass(this.element,"cc-invisible")}else this.element=u.call(this,i);b.call(this),y.call(this),this.options.autoOpen&&this.autoOpen()},n.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,f(this.options.palette),this.options=null},n.prototype.open=function(t){if(this.element)return this.isOpen()||(e.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},n.prototype.close=function(t){if(this.element)return this.isOpen()&&(e.hasTransition?this.fadeOut():this.element.style.display="none",t&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},n.prototype.fadeIn=function(){var i=this.element;if(e.hasTransition&&i&&(this.afterTransition&&s.call(this,i),t.hasClass(i,"cc-invisible"))){if(i.style.display="",this.options["static"]){var n=this.element.clientHeight;this.element.parentNode.style.maxHeight=n+"px"}var r=20;this.openingTimeout=setTimeout(o.bind(this,i),r)}},n.prototype.fadeOut=function(){var i=this.element;e.hasTransition&&i&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),o.bind(this,i)),t.hasClass(i,"cc-invisible")||(this.options["static"]&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=s.bind(this,i),i.addEventListener(e.transitionEnd,this.afterTransition),t.addClass(i,"cc-invisible")))},n.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!e.hasTransition||!t.hasClass(this.element,"cc-invisible"))},n.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},n.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},n.prototype.hasAnswered=function(t){return Object.keys(e.status).indexOf(this.getStatus())>=0},n.prototype.hasConsented=function(t){var i=this.getStatus();return i==e.status.allow||i==e.status.dismiss},n.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled&&this.open()},n.prototype.setStatus=function(i){var n=this.options.cookie,o=t.getCookie(n.name),s=Object.keys(e.status).indexOf(o)>=0;Object.keys(e.status).indexOf(i)>=0?(t.setCookie(n.name,i,n.expiryDays,n.domain,n.path),this.options.onStatusChange.call(this,i,s)):this.clearStatus()},n.prototype.getStatus=function(){return t.getCookie(this.options.cookie.name)},n.prototype.clearStatus=function(){var e=this.options.cookie;t.setCookie(e.name,"",-1,e.domain,e.path)},n}(),e.Location=function(){function e(e){t.deepExtend(this.options={},s),t.isPlainObject(e)&&t.deepExtend(this.options,e),this.currentServiceIndex=-1}function i(e,t,i){var n,o=document.createElement("script");o.type="text/"+(e.type||"javascript"),o.src=e.src||e,o.async=!1,o.onreadystatechange=o.onload=function(){var e=o.readyState;clearTimeout(n),t.done||e&&!/loaded|complete/.test(e)||(t.done=!0,t(),o.onreadystatechange=o.onload=null)},document.body.appendChild(o),n=setTimeout(function(){t.done=!0,t(),o.onreadystatechange=o.onload=null},i)}function n(e,t,i,n,o){var s=new(window.XMLHttpRequest||window.ActiveXObject)("MSXML2.XMLHTTP.3.0");if(s.open(n?"POST":"GET",e,1),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),Array.isArray(o))for(var r=0,a=o.length;r<a;++r){var c=o[r].split(":",2);s.setRequestHeader(c[0].replace(/^\s+|\s+$/g,""),c[1].replace(/^\s+|\s+$/g,""))}"function"==typeof t&&(s.onreadystatechange=function(){s.readyState>3&&t(s)}),s.send(n)}function o(e){return new Error("Error ["+(e.code||"UNKNOWN")+"]: "+e.error)}var s={timeout:5e3,services:["freegeoip","ipinfo","maxmind"],serviceDefinitions:{freegeoip:function(){return{url:"//freegeoip.net/json/?callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return i.error?o(i):{code:i.country_code}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var i=JSON.parse(t);return i.error?o(i):{code:i.country}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return"ERROR"==i.statusCode?o({error:i.statusMessage}):{code:i.countryCode}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(e){return window.geoip2?void geoip2.country(function(t){try{e({code:t.country.iso_code})}catch(i){e(o(i))}},function(t){e(o(t))}):void e(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}};return e.prototype.getNextService=function(){var e;do e=this.getServiceByIdx(++this.currentServiceIndex);while(this.currentServiceIndex<this.options.services.length&&!e);return e},e.prototype.getServiceByIdx=function(e){var i=this.options.services[e];if("function"==typeof i){var n=i();return n.name&&t.deepExtend(n,this.options.serviceDefinitions[n.name](n)),n}return"string"==typeof i?this.options.serviceDefinitions[i]():t.isPlainObject(i)?this.options.serviceDefinitions[i.name](i):null},e.prototype.locate=function(e,t){var i=this.getNextService();return i?(this.callbackComplete=e,this.callbackError=t,void this.runService(i,this.runNextServiceOnError.bind(this))):void t(new Error("No services to run"))},e.prototype.setupUrl=function(e){var t=this.getCurrentServiceOpts();return e.url.replace(/\{(.*?)\}/g,function(i,n){if("callback"===n){var o="callback"+Date.now();return window[o]=function(t){e.__JSONP_DATA=JSON.stringify(t)},o}if(n in t.interpolateUrl)return t.interpolateUrl[n]})},e.prototype.runService=function(e,t){var o=this;if(e&&e.url&&e.callback){var s=e.isScript?i:n,r=this.setupUrl(e);s(r,function(i){var n=i?i.responseText:"";e.__JSONP_DATA&&(n=e.__JSONP_DATA,delete e.__JSONP_DATA),o.runServiceCallback.call(o,t,e,n)},this.options.timeout,e.data,e.headers)}},e.prototype.runServiceCallback=function(e,t,i){var n=this,o=function(t){s||n.onServiceResult.call(n,e,t)},s=t.callback(o,i);s&&this.onServiceResult.call(this,e,s)},e.prototype.onServiceResult=function(e,t){t instanceof Error||t&&t.error?e.call(this,t,null):e.call(this,null,t)},e.prototype.runNextServiceOnError=function(e,t){if(e){this.logError(e);var i=this.getNextService();i?this.runService(i,this.runNextServiceOnError.bind(this)):this.completeService.call(this,this.callbackError,new Error("All services failed"))}else this.completeService.call(this,this.callbackComplete,t)},e.prototype.getCurrentServiceOpts=function(){var e=this.options.services[this.currentServiceIndex];return"string"==typeof e?{name:e}:"function"==typeof e?e():t.isPlainObject(e)?e:{}},e.prototype.completeService=function(e,t){this.currentServiceIndex=-1,e&&e(t)},e.prototype.logError=function(e){var t=this.currentServiceIndex,i=this.getServiceByIdx(t);console.error("The service["+t+"] ("+i.url+") responded with the following error",e)},e}(),e.Law=function(){function e(e){this.initialise.apply(this,arguments)}var i={regionalLaw:!0,hasLaw:["AT","BE","BG","HR","CZ","CY","DK","EE","FI","FR","DE","EL","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","SK","SI","ES","SE","GB","UK"],revokable:["HR","CY","DK","EE","FR","DE","LV","LT","NL","PT","ES"],explicitAction:["HR","IT","ES"]};return e.prototype.initialise=function(e){t.deepExtend(this.options={},i),t.isPlainObject(e)&&t.deepExtend(this.options,e)},e.prototype.get=function(e){var t=this.options;return{hasLaw:t.hasLaw.indexOf(e)>=0,revokable:t.revokable.indexOf(e)>=0,explicitAction:t.explicitAction.indexOf(e)>=0}},e.prototype.applyLaw=function(e,t){var i=this.get(t);return i.hasLaw||(e.enabled=!1),this.options.regionalLaw&&(i.revokable&&(e.revokable=!0),i.explicitAction&&(e.dismissOnScroll=!1,e.dismissOnTimeout=!1)),e},e}(),e.initialise=function(t,i,n){var o=new e.Law(t.law);i||(i=function(){}),n||(n=function(){}),e.getCountryCode(t,function(n){delete t.law,delete t.location,n.code&&(t=o.applyLaw(t,n.code)),i(new e.Popup(t))},function(i){delete t.law,delete t.location,n(i,new e.Popup(t))})},e.getCountryCode=function(t,i,n){if(t.law&&t.law.countryCode)return void i({code:t.law.countryCode});if(t.location){var o=new e.Location(t.location);return void o.locate(function(e){i(e||{})},n)}i({})},e.utils=t,e.hasInitialised=!0,window.cookieconsent=e}}(window.cookieconsent||{});
\ No newline at end of file diff --git a/phpBB/common.php b/phpBB/common.php index d12966168b..70feb55d04 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -12,7 +12,7 @@  */  /** -* Minimum Requirement: PHP 5.3.9 +* Minimum Requirement: PHP 5.4.0  */  if (!defined('IN_PHPBB')) @@ -20,6 +20,11 @@ if (!defined('IN_PHPBB'))  	exit;  } +if (version_compare(PHP_VERSION, '5.4') < 0) +{ +	die('You are running an unsupported PHP version. Please upgrade to PHP 5.4.0 or higher before trying to install or update to phpBB 3.2'); +} +  require($phpbb_root_path . 'includes/startup.' . $phpEx);  require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx); diff --git a/phpBB/composer.json b/phpBB/composer.json index e91430023d..976c3a74cd 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.8.0", +		"s9e/text-formatter": "~0.9.0",  		"symfony/config": "^2.8",  		"symfony/console": "^2.8",  		"symfony/debug": "^2.8", @@ -55,7 +55,7 @@  		"laravel/homestead": "~2.2",  		"phing/phing": "2.4.*",  		"phpunit/dbunit": "1.3.*", -		"phpunit/phpunit": "4.1.*", +		"phpunit/phpunit": "^4.1",  		"sami/sami": "1.*",  		"squizlabs/php_codesniffer": "2.*",  		"symfony/browser-kit": "^2.8", diff --git a/phpBB/composer.lock b/phpBB/composer.lock index e550572fb3..427fbe4d1b 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": "067b099cc97334a6a08a77e5648aa260", -    "content-hash": "90198ca524b93a7e915aa6916b2f55af", +    "hash": "fa77bb5667bcac933b072b639a44aec0", +    "content-hash": "da4fd9fbb589d2cffaa3f0168875475d",      "packages": [          {              "name": "bantu/ini-get-wrapper", @@ -658,16 +658,16 @@          },          {              "name": "s9e/text-formatter", -            "version": "0.8.4", +            "version": "0.9.1",              "source": {                  "type": "git",                  "url": "https://github.com/s9e/TextFormatter.git", -                "reference": "919fd772aae4dd889618da1cb18ae746f2a14bb6" +                "reference": "e0f1d477d5c24dff11fa3aaa408d8ead07006fe3"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/919fd772aae4dd889618da1cb18ae746f2a14bb6", -                "reference": "919fd772aae4dd889618da1cb18ae746f2a14bb6", +                "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/e0f1d477d5c24dff11fa3aaa408d8ead07006fe3", +                "reference": "e0f1d477d5c24dff11fa3aaa408d8ead07006fe3",                  "shasum": ""              },              "require": { @@ -676,6 +676,11 @@                  "lib-pcre": ">=7.2",                  "php": ">=5.3.3"              }, +            "require-dev": { +                "matthiasmullie/minify": "*", +                "php": ">=5.3.3", +                "s9e/regexp-builder": ">=1.3.0" +            },              "suggest": {                  "ext-curl": "Improves the performance of the MediaEmbed plugin and some JavaScript minifiers",                  "ext-intl": "Allows international URLs to be accepted by the URL filter", @@ -714,7 +719,7 @@                  "parser",                  "shortcodes"              ], -            "time": "2016-11-22 20:10:24" +            "time": "2017-01-22 17:12:21"          },          {              "name": "symfony/config", @@ -1895,6 +1900,60 @@      ],      "packages-dev": [          { +            "name": "doctrine/instantiator", +            "version": "1.0.5", +            "source": { +                "type": "git", +                "url": "https://github.com/doctrine/instantiator.git", +                "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" +            }, +            "dist": { +                "type": "zip", +                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", +                "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", +                "shasum": "" +            }, +            "require": { +                "php": ">=5.3,<8.0-DEV" +            }, +            "require-dev": { +                "athletic/athletic": "~0.1.8", +                "ext-pdo": "*", +                "ext-phar": "*", +                "phpunit/phpunit": "~4.0", +                "squizlabs/php_codesniffer": "~2.0" +            }, +            "type": "library", +            "extra": { +                "branch-alias": { +                    "dev-master": "1.0.x-dev" +                } +            }, +            "autoload": { +                "psr-4": { +                    "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" +                } +            }, +            "notification-url": "https://packagist.org/downloads/", +            "license": [ +                "MIT" +            ], +            "authors": [ +                { +                    "name": "Marco Pivetta", +                    "email": "ocramius@gmail.com", +                    "homepage": "http://ocramius.github.com/" +                } +            ], +            "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", +            "homepage": "https://github.com/doctrine/instantiator", +            "keywords": [ +                "constructor", +                "instantiate" +            ], +            "time": "2015-06-14 21:17:01" +        }, +        {              "name": "fabpot/goutte",              "version": "v2.0.4",              "source": { @@ -2179,6 +2238,118 @@              "time": "2012-11-29 21:23:47"          },          { +            "name": "phpdocumentor/reflection-docblock", +            "version": "2.0.4", +            "source": { +                "type": "git", +                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", +                "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" +            }, +            "dist": { +                "type": "zip", +                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", +                "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", +                "shasum": "" +            }, +            "require": { +                "php": ">=5.3.3" +            }, +            "require-dev": { +                "phpunit/phpunit": "~4.0" +            }, +            "suggest": { +                "dflydev/markdown": "~1.0", +                "erusev/parsedown": "~1.0" +            }, +            "type": "library", +            "extra": { +                "branch-alias": { +                    "dev-master": "2.0.x-dev" +                } +            }, +            "autoload": { +                "psr-0": { +                    "phpDocumentor": [ +                        "src/" +                    ] +                } +            }, +            "notification-url": "https://packagist.org/downloads/", +            "license": [ +                "MIT" +            ], +            "authors": [ +                { +                    "name": "Mike van Riel", +                    "email": "mike.vanriel@naenius.com" +                } +            ], +            "time": "2015-02-03 12:10:50" +        }, +        { +            "name": "phpspec/prophecy", +            "version": "v1.6.2", +            "source": { +                "type": "git", +                "url": "https://github.com/phpspec/prophecy.git", +                "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" +            }, +            "dist": { +                "type": "zip", +                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", +                "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", +                "shasum": "" +            }, +            "require": { +                "doctrine/instantiator": "^1.0.2", +                "php": "^5.3|^7.0", +                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", +                "sebastian/comparator": "^1.1", +                "sebastian/recursion-context": "^1.0|^2.0" +            }, +            "require-dev": { +                "phpspec/phpspec": "^2.0", +                "phpunit/phpunit": "^4.8 || ^5.6.5" +            }, +            "type": "library", +            "extra": { +                "branch-alias": { +                    "dev-master": "1.6.x-dev" +                } +            }, +            "autoload": { +                "psr-0": { +                    "Prophecy\\": "src/" +                } +            }, +            "notification-url": "https://packagist.org/downloads/", +            "license": [ +                "MIT" +            ], +            "authors": [ +                { +                    "name": "Konstantin Kudryashov", +                    "email": "ever.zet@gmail.com", +                    "homepage": "http://everzet.com" +                }, +                { +                    "name": "Marcello Duarte", +                    "email": "marcello.duarte@gmail.com" +                } +            ], +            "description": "Highly opinionated mocking framework for PHP 5.3+", +            "homepage": "https://github.com/phpspec/prophecy", +            "keywords": [ +                "Double", +                "Dummy", +                "fake", +                "mock", +                "spy", +                "stub" +            ], +            "time": "2016-11-21 14:58:47" +        }, +        {              "name": "phpunit/dbunit",              "version": "1.3.2",              "source": { @@ -2301,31 +2472,33 @@          },          {              "name": "phpunit/php-file-iterator", -            "version": "1.3.4", +            "version": "1.4.2",              "source": {                  "type": "git",                  "url": "https://github.com/sebastianbergmann/php-file-iterator.git", -                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" +                "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", -                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", +                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", +                "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",                  "shasum": ""              },              "require": {                  "php": ">=5.3.3"              },              "type": "library", +            "extra": { +                "branch-alias": { +                    "dev-master": "1.4.x-dev" +                } +            },              "autoload": {                  "classmap": [ -                    "File/" +                    "src/"                  ]              },              "notification-url": "https://packagist.org/downloads/", -            "include-path": [ -                "" -            ],              "license": [                  "BSD-3-Clause"              ], @@ -2342,7 +2515,7 @@                  "filesystem",                  "iterator"              ], -            "time": "2013-10-10 15:34:57" +            "time": "2016-10-03 07:40:28"          },          {              "name": "phpunit/php-text-template", @@ -2480,16 +2653,16 @@          },          {              "name": "phpunit/phpunit", -            "version": "4.1.6", +            "version": "4.8.31",              "source": {                  "type": "git",                  "url": "https://github.com/sebastianbergmann/phpunit.git", -                "reference": "241116219bb7e3b8111a36ffd8f37546888738d6" +                "reference": "98b2b39a520766bec663ff5b7ff1b729db9dbfe3"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/241116219bb7e3b8111a36ffd8f37546888738d6", -                "reference": "241116219bb7e3b8111a36ffd8f37546888738d6", +                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/98b2b39a520766bec663ff5b7ff1b729db9dbfe3", +                "reference": "98b2b39a520766bec663ff5b7ff1b729db9dbfe3",                  "shasum": ""              },              "require": { @@ -2499,17 +2672,19 @@                  "ext-reflection": "*",                  "ext-spl": "*",                  "php": ">=5.3.3", -                "phpunit/php-code-coverage": "~2.0", -                "phpunit/php-file-iterator": "~1.3.1", +                "phpspec/prophecy": "^1.3.1", +                "phpunit/php-code-coverage": "~2.1", +                "phpunit/php-file-iterator": "~1.4",                  "phpunit/php-text-template": "~1.2", -                "phpunit/php-timer": "~1.0.2", -                "phpunit/phpunit-mock-objects": "2.1.5", -                "sebastian/comparator": "~1.0", -                "sebastian/diff": "~1.1", -                "sebastian/environment": "~1.0", -                "sebastian/exporter": "~1.0", +                "phpunit/php-timer": "^1.0.6", +                "phpunit/phpunit-mock-objects": "~2.3", +                "sebastian/comparator": "~1.2.2", +                "sebastian/diff": "~1.2", +                "sebastian/environment": "~1.3", +                "sebastian/exporter": "~1.2", +                "sebastian/global-state": "~1.0",                  "sebastian/version": "~1.0", -                "symfony/yaml": "~2.0" +                "symfony/yaml": "~2.1|~3.0"              },              "suggest": {                  "phpunit/php-invoker": "~1.1" @@ -2520,7 +2695,7 @@              "type": "library",              "extra": {                  "branch-alias": { -                    "dev-master": "4.1.x-dev" +                    "dev-master": "4.8.x-dev"                  }              },              "autoload": { @@ -2529,10 +2704,6 @@                  ]              },              "notification-url": "https://packagist.org/downloads/", -            "include-path": [ -                "", -                "../../symfony/yaml/" -            ],              "license": [                  "BSD-3-Clause"              ], @@ -2544,34 +2715,36 @@                  }              ],              "description": "The PHP Unit Testing framework.", -            "homepage": "http://www.phpunit.de/", +            "homepage": "https://phpunit.de/",              "keywords": [                  "phpunit",                  "testing",                  "xunit"              ], -            "time": "2014-08-17 08:07:02" +            "time": "2016-12-09 02:45:31"          },          {              "name": "phpunit/phpunit-mock-objects", -            "version": "2.1.5", +            "version": "2.3.8",              "source": {                  "type": "git",                  "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", -                "reference": "7878b9c41edb3afab92b85edf5f0981014a2713a" +                "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/7878b9c41edb3afab92b85edf5f0981014a2713a", -                "reference": "7878b9c41edb3afab92b85edf5f0981014a2713a", +                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", +                "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",                  "shasum": ""              },              "require": { +                "doctrine/instantiator": "^1.0.2",                  "php": ">=5.3.3", -                "phpunit/php-text-template": "~1.2" +                "phpunit/php-text-template": "~1.2", +                "sebastian/exporter": "~1.2"              },              "require-dev": { -                "phpunit/phpunit": "~4.1" +                "phpunit/phpunit": "~4.4"              },              "suggest": {                  "ext-soap": "*" @@ -2579,7 +2752,7 @@              "type": "library",              "extra": {                  "branch-alias": { -                    "dev-master": "2.1.x-dev" +                    "dev-master": "2.3.x-dev"                  }              },              "autoload": { @@ -2588,9 +2761,6 @@                  ]              },              "notification-url": "https://packagist.org/downloads/", -            "include-path": [ -                "" -            ],              "license": [                  "BSD-3-Clause"              ], @@ -2607,7 +2777,7 @@                  "mock",                  "xunit"              ], -            "time": "2014-06-12 07:22:15" +            "time": "2015-10-02 06:51:40"          },          {              "name": "pimple/pimple", @@ -2644,9 +2814,7 @@              "authors": [                  {                      "name": "Fabien Potencier", -                    "email": "fabien@symfony.com", -                    "homepage": "http://fabien.potencier.org", -                    "role": "Lead Developer" +                    "email": "fabien@symfony.com"                  }              ],              "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", @@ -2948,6 +3116,57 @@              "time": "2016-06-17 09:04:28"          },          { +            "name": "sebastian/global-state", +            "version": "1.1.1", +            "source": { +                "type": "git", +                "url": "https://github.com/sebastianbergmann/global-state.git", +                "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" +            }, +            "dist": { +                "type": "zip", +                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", +                "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", +                "shasum": "" +            }, +            "require": { +                "php": ">=5.3.3" +            }, +            "require-dev": { +                "phpunit/phpunit": "~4.2" +            }, +            "suggest": { +                "ext-uopz": "*" +            }, +            "type": "library", +            "extra": { +                "branch-alias": { +                    "dev-master": "1.0-dev" +                } +            }, +            "autoload": { +                "classmap": [ +                    "src/" +                ] +            }, +            "notification-url": "https://packagist.org/downloads/", +            "license": [ +                "BSD-3-Clause" +            ], +            "authors": [ +                { +                    "name": "Sebastian Bergmann", +                    "email": "sebastian@phpunit.de" +                } +            ], +            "description": "Snapshotting of global state", +            "homepage": "http://www.github.com/sebastianbergmann/global-state", +            "keywords": [ +                "global state" +            ], +            "time": "2015-10-12 03:26:01" +        }, +        {              "name": "sebastian/recursion-context",              "version": "1.0.4",              "source": { diff --git a/phpBB/config/default/container/services_db.yml b/phpBB/config/default/container/services_db.yml index d7a8238400..d538177603 100644 --- a/phpBB/config/default/container/services_db.yml +++ b/phpBB/config/default/container/services_db.yml @@ -5,9 +5,7 @@ services:              - '@service_container'      dbal.conn.driver: -        class: '%dbal.driver.class%' -        calls: -            - [sql_connect, ['%dbal.dbhost%', '%dbal.dbuser%', '%dbal.dbpasswd%', '%dbal.dbname%', '%dbal.dbport%', false, '%dbal.new_link%']] +        synthetic: true  # ----- DB Tools -----      dbal.tools.factory: diff --git a/phpBB/config/installer/container/services_install_data.yml b/phpBB/config/installer/container/services_install_data.yml index df63d16d0d..5de00170e9 100644 --- a/phpBB/config/installer/container/services_install_data.yml +++ b/phpBB/config/installer/container/services_install_data.yml @@ -29,6 +29,16 @@ services:          tags:              - { name: install_data_install, order: 30 } +    installer.install_data.create_search_index: +        class: phpbb\install\module\install_data\task\create_search_index +        arguments: +            - '@config' +            - '@installer.helper.container_factory' +            - '%core.root_path%' +            - '%core.php_ext%' +        tags: +            - { name: install_data_install, order: 40 } +      installer.module.data_install_collection:          class: phpbb\di\ordered_service_collection          arguments: diff --git a/phpBB/develop/test.gif b/phpBB/develop/test.gifBinary files differ new file mode 100644 index 0000000000..0dbc9b0459 --- /dev/null +++ b/phpBB/develop/test.gif diff --git a/phpBB/docs/CREDITS.txt b/phpBB/docs/CREDITS.txt index 26ff8fcc80..2df7543ce1 100644 --- a/phpBB/docs/CREDITS.txt +++ b/phpBB/docs/CREDITS.txt @@ -75,9 +75,7 @@ Major contributions by:  leviatan21 (Gabriel Vazquez)  Visual Confirmation:   Xore (Robert Hetzler) -Original subSilver by subBlue Design, Tom Beddard, (c) 2001 phpBB Limited  prosilver by subBlue Design, Tom Beddard, (c) 2004 phpBB Limited -subsilver2 by subBlue Design, Tom Beddard, (c) 2004 phpBB Limited  phpBB contains code from the following applications: @@ -99,4 +97,5 @@ Pear (c) 2001-2004 PHP Group, http://pear.php.net  Text_Diff-0.2.1 http://pear.php.net/package/Text_Diff  MIT licenced: -Symfony2 (c) 2004-2011 Fabien Potencier, http://symfony.com/ +Symfony2 (c) 2004-2011 Fabien Potencier, https://symfony.com/ +Cookie Consent (c) 2015 Silktide Ltd, https://cookieconsent.insites.com diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index 59fc184136..9b0d70b46b 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -58,12 +58,30 @@ acp_email_options_after  * Since: 3.1.2-RC1  * Purpose: Add settings to mass email form +acp_ext_details_end +=== +* Location: adm/style/acp_ext_details.html +* Since: 3.1.11-RC1 +* Purpose: Add more detailed information on extension after the available information. + +acp_ext_list_disabled_name_after +=== +* Location: adm/style/acp_ext_list.html +* Since: 3.1.11-RC1 +* Purpose: Add content after the name of disabled extensions in the list +  acp_ext_list_disabled_title_after  ===  * Location: adm/style/acp_ext_list.html  * Since: 3.1.11-RC1  * Purpose: Add text after disabled extensions section title. +acp_ext_list_enabled_name_after +=== +* Location: adm/style/acp_ext_list.html +* Since: 3.1.11-RC1 +* Purpose: Add content after the name of enabled extensions in the list +  acp_ext_list_enabled_title_after  ===  * Location: adm/style/acp_ext_list.html @@ -1010,6 +1028,20 @@ memberlist_search_sorting_options_before  * Since: 3.1.2-RC1  * Purpose: Add information before the search sorting options field. +memberlist_team_username_append +=== +* Locations: +    + styles/prosilver/template/memberlist_team.html +* Since: 3.1.11-RC1 +* Purpose: Append information to username of team member + +memberlist_team_username_prepend +=== +* Locations: +    + styles/prosilver/template/memberlist_team.html +* Since: 3.1.11-RC1 +* Purpose: Add information before team user username +  memberlist_view_contact_after  ===  * Locations: diff --git a/phpBB/download/file.php b/phpBB/download/file.php index 7a20145968..a9cd4a3b3c 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -272,7 +272,7 @@ else  	* @var	string	mode				Download mode  	* @var	bool	thumbnail			Flag indicating if the file is a thumbnail  	* @since 3.1.6-RC1 -	* @change 3.1.7-RC1	Fixing wrong name of a variable (replacing "extension" by "extensions") +	* @changed 3.1.7-RC1	Fixing wrong name of a variable (replacing "extension" by "extensions")  	*/  	$vars = array(  		'attach_id', diff --git a/phpBB/images/icons/misc/fire.gif b/phpBB/images/icons/misc/fire.gifBinary files differ index e436d6e8c9..4adba205e5 100644 --- a/phpBB/images/icons/misc/fire.gif +++ b/phpBB/images/icons/misc/fire.gif diff --git a/phpBB/images/icons/misc/heart.gif b/phpBB/images/icons/misc/heart.gifBinary files differ index c626dcb99f..c391c37433 100644 --- a/phpBB/images/icons/misc/heart.gif +++ b/phpBB/images/icons/misc/heart.gif diff --git a/phpBB/images/icons/misc/radioactive.gif b/phpBB/images/icons/misc/radioactive.gifBinary files differ index 517ae6397b..6d7527c03e 100644 --- a/phpBB/images/icons/misc/radioactive.gif +++ b/phpBB/images/icons/misc/radioactive.gif diff --git a/phpBB/images/icons/misc/star.gif b/phpBB/images/icons/misc/star.gifBinary files differ index dcde6eb66e..15a96ef87a 100644 --- a/phpBB/images/icons/misc/star.gif +++ b/phpBB/images/icons/misc/star.gif diff --git a/phpBB/images/icons/misc/thinking.gif b/phpBB/images/icons/misc/thinking.gifBinary files differ index fdec41bc19..23f226774d 100644 --- a/phpBB/images/icons/misc/thinking.gif +++ b/phpBB/images/icons/misc/thinking.gif diff --git a/phpBB/images/icons/smile/alert.gif b/phpBB/images/icons/smile/alert.gifBinary files differ index 024e2a969a..b0e1fe1737 100644 --- a/phpBB/images/icons/smile/alert.gif +++ b/phpBB/images/icons/smile/alert.gif diff --git a/phpBB/images/icons/smile/info.gif b/phpBB/images/icons/smile/info.gifBinary files differ index d715ac7c75..2b28d8c83a 100644 --- a/phpBB/images/icons/smile/info.gif +++ b/phpBB/images/icons/smile/info.gif diff --git a/phpBB/images/icons/smile/mrgreen.gif b/phpBB/images/icons/smile/mrgreen.gifBinary files differ index 9cd2715824..f6da47a117 100644 --- a/phpBB/images/icons/smile/mrgreen.gif +++ b/phpBB/images/icons/smile/mrgreen.gif diff --git a/phpBB/images/icons/smile/question.gif b/phpBB/images/icons/smile/question.gifBinary files differ index a07c038a9b..2c82028417 100644 --- a/phpBB/images/icons/smile/question.gif +++ b/phpBB/images/icons/smile/question.gif diff --git a/phpBB/images/icons/smile/redface.gif b/phpBB/images/icons/smile/redface.gifBinary files differ index 50e7ce3bfa..85c81f061c 100644 --- a/phpBB/images/icons/smile/redface.gif +++ b/phpBB/images/icons/smile/redface.gif diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 02af98ec54..1f9c15dbd0 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -196,6 +196,7 @@ class acp_board  						'allow_post_flash'		=> array('lang' => 'ALLOW_POST_FLASH',		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true),  						'allow_smilies'			=> array('lang' => 'ALLOW_SMILIES',			'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => false),  						'allow_post_links'		=> array('lang' => 'ALLOW_POST_LINKS',		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true), +						'allowed_schemes_links'	=> array('lang' => 'ALLOWED_SCHEMES_LINKS',	'validate' => 'string',	'type' => 'text:0:255', 'explain' => true),  						'allow_nocensors'		=> array('lang' => 'ALLOW_NO_CENSORS',		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true),  						'allow_bookmarks'		=> array('lang' => 'ALLOW_BOOKMARKS',		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true),  						'enable_post_confirm'	=> array('lang' => 'VISUAL_CONFIRM_POST',	'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true), @@ -323,6 +324,7 @@ class acp_board  						'cookie_name'	=> array('lang' => 'COOKIE_NAME',	'validate' => 'string',	'type' => 'text::16', 'explain' => false),  						'cookie_path'	=> array('lang'	=> 'COOKIE_PATH',	'validate' => 'string',	'type' => 'text::255', 'explain' => false),  						'cookie_secure'	=> array('lang' => 'COOKIE_SECURE',	'validate' => 'bool',	'type' => 'radio:disabled_enabled', 'explain' => true), +						'cookie_notice'	=> array('lang' => 'COOKIE_NOTICE',	'validate' => 'bool',	'type' => 'radio:enabled_disabled', 'explain' => true),  					)  				);  			break; @@ -551,6 +553,12 @@ class acp_board  			}  		} +		// Invalidate the text_formatter cache when posting options are changed +		if ($mode == 'post' && $submit) +		{ +			$phpbb_container->get('text_formatter.cache')->invalidate(); +		} +  		// Store news and exclude ids  		if ($mode == 'feed' && $submit)  		{ diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index 8dec7c69bd..bb85d080ce 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -429,24 +429,32 @@ class acp_main  		// Version check  		$user->add_lang('install'); -		if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.4', '<')) +		if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.4.0', '<'))  		{  			$template->assign_vars(array(  				'S_PHP_VERSION_OLD'	=> true, -				'L_PHP_VERSION_OLD'	=> sprintf($user->lang['PHP_VERSION_OLD'], '<a href="https://www.phpbb.com/community/viewtopic.php?f=14&t=2152375">', '</a>'), +				'L_PHP_VERSION_OLD'	=> sprintf($user->lang['PHP_VERSION_OLD'], PHP_VERSION, '5.4.0', '<a href="https://www.phpbb.com/support/docs/en/3.2/ug/quickstart/requirements">', '</a>'),  			));  		}  		if ($auth->acl_get('a_board'))  		{ -			/* @var $version_helper \phpbb\version_helper */  			$version_helper = $phpbb_container->get('version_helper');  			try  			{  				$recheck = $request->variable('versioncheck_force', false); -				$updates_available = $version_helper->get_suggested_updates($recheck); +				$updates_available = $version_helper->get_update_on_branch($recheck); +				$upgrades_available = $version_helper->get_suggested_updates(); +				if (!empty($upgrades_available)) +				{ +					$upgrades_available = array_pop($upgrades_available); +				} -				$template->assign_var('S_VERSION_UP_TO_DATE', empty($updates_available)); +				$template->assign_vars(array( +					'S_VERSION_UP_TO_DATE'		=> empty($updates_available), +					'S_VERSION_UPGRADEABLE'		=> !empty($upgrades_available), +					'UPGRADE_INSTRUCTIONS'		=> !empty($upgrades_available) ? $user->lang('UPGRADE_INSTRUCTIONS', $upgrades_available['current'], $upgrades_available['announcement']) : false, +				));  			}  			catch (\RuntimeException $e)  			{ diff --git a/phpBB/includes/acp/acp_update.php b/phpBB/includes/acp/acp_update.php index b88e6d3984..df376765f8 100644 --- a/phpBB/includes/acp/acp_update.php +++ b/phpBB/includes/acp/acp_update.php @@ -38,7 +38,12 @@ class acp_update  		try  		{  			$recheck = $request->variable('versioncheck_force', false); -			$updates_available = $version_helper->get_suggested_updates($recheck); +			$updates_available = $version_helper->get_update_on_branch($recheck); +			$upgrades_available = $version_helper->get_suggested_updates(); +			if (!empty($upgrades_available)) +			{ +				$upgrades_available = array_pop($upgrades_available); +			}  		}  		catch (\RuntimeException $e)  		{ @@ -62,6 +67,8 @@ class acp_update  			'CURRENT_VERSION'		=> $config['version'],  			'UPDATE_INSTRUCTIONS'	=> sprintf($user->lang['UPDATE_INSTRUCTIONS'], $update_link), +			'S_VERSION_UPGRADEABLE'		=> !empty($upgrades_available), +			'UPGRADE_INSTRUCTIONS'		=> !empty($upgrades_available) ? $user->lang('UPGRADE_INSTRUCTIONS', $upgrades_available['current'], $upgrades_available['announcement']) : false,  		));  		// Incomplete update? diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 25e9d6f658..5a2b1445dc 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -2018,7 +2018,9 @@ class acp_users  				$enable_smilies	= ($config['allow_sig_smilies']) ? $this->optionget($user_row, 'sig_smilies') : false;  				$enable_urls	= ($config['allow_sig_links']) ? $this->optionget($user_row, 'sig_links') : false; -				$decoded_message	= generate_text_for_edit($user_row['user_sig'], $user_row['user_sig_bbcode_uid'], $user_row['user_sig_bbcode_bitfield']); +				$bbcode_flags = ($enable_bbcode ? OPTION_FLAG_BBCODE : 0) + ($enable_smilies ? OPTION_FLAG_SMILIES : 0) + ($enable_urls ? OPTION_FLAG_LINKS : 0); + +				$decoded_message	= generate_text_for_edit($user_row['user_sig'], $user_row['user_sig_bbcode_uid'], $bbcode_flags);  				$signature			= $request->variable('signature', $decoded_message['text'], true);  				$signature_preview	= ''; diff --git a/phpBB/includes/acp/info/acp_logs.php b/phpBB/includes/acp/info/acp_logs.php index efa35b2118..1be7b2883d 100644 --- a/phpBB/includes/acp/info/acp_logs.php +++ b/phpBB/includes/acp/info/acp_logs.php @@ -15,15 +15,30 @@ class acp_logs_info  {  	function module()  	{ +		global $phpbb_dispatcher; + +		$modes = array( +			'admin'		=> array('title' => 'ACP_ADMIN_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), +			'mod'		=> array('title' => 'ACP_MOD_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), +			'users'		=> array('title' => 'ACP_USERS_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), +			'critical'	=> array('title' => 'ACP_CRITICAL_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), +		); + +		/** +		* Event to add or modify ACP log modulemodes +		* +		* @event core.acp_logs_info_modify_modes +		* @var	array	modes	Array with modes info +		* @since 3.1.11-RC1 +		* @since 3.2.1-RC1 +		*/ +		$vars = array('modes'); +		extract($phpbb_dispatcher->trigger_event('core.acp_logs_info_modify_modes', compact($vars))); +  		return array(  			'filename'	=> 'acp_logs',  			'title'		=> 'ACP_LOGGING', -			'modes'		=> array( -				'admin'		=> array('title' => 'ACP_ADMIN_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), -				'mod'		=> array('title' => 'ACP_MOD_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), -				'users'		=> array('title' => 'ACP_USERS_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), -				'critical'	=> array('title' => 'ACP_CRITICAL_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), -			), +			'modes'		=> $modes,  		);  	} diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index a6a5bf41cb..440064140c 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))  */  // phpBB Version -@define('PHPBB_VERSION', '3.2.0-RC3-dev'); +@define('PHPBB_VERSION', '3.2.1-dev');  // QA-related  // define('PHPBB_QA', 1); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 39d22254a2..3dabd1b46e 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -4454,6 +4454,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id =  		'T_FONT_AWESOME_LINK'	=> !empty($config['allow_cdn']) && !empty($config['load_font_awesome_url']) ? $config['load_font_awesome_url'] : "{$web_path}assets/css/font-awesome.min.css?assets_version=" . $config['assets_version'],  		'T_JQUERY_LINK'			=> !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.min.js?assets_version=" . $config['assets_version'],  		'S_ALLOW_CDN'			=> !empty($config['allow_cdn']), +		'S_COOKIE_NOTICE'		=> !empty($config['cookie_notice']),  		'T_THEME_NAME'			=> rawurlencode($user->style['style_path']),  		'T_THEME_LANG_NAME'		=> $user->data['user_lang'], diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index 9ec965a6a1..387606a300 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -686,7 +686,7 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb  	* @var bool		allow_url_bbcode	Whether or not to parse the [url] BBCode  	* @var string	mode				Mode to parse text as, e.g. post or sig  	* @since 3.1.0-a1 -	* @changed 3.2.0-a1 +	* @changed 3.2.0-a1 Added mode  	*/  	$vars = array(  		'text', diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 326378d815..c8b5ec8b1a 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -442,7 +442,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod  			* @var	array	root_data		Array with the root forum data  			* @var	array	row				The data of the 'category'  			* @since 3.1.0-RC4 -			* @change 3.1.7-RC1 Removed undefined catless variable +			* @changed 3.1.7-RC1 Removed undefined catless variable  			*/  			$vars = array(  				'cat_row', @@ -648,7 +648,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod  		* @var	array	row				The data of the forum  		* @var	array	subforums_row	Template data of subforums  		* @since 3.1.0-a1 -		* @change 3.1.0-b5 Added var subforums_row +		* @changed 3.1.0-b5 Added var subforums_row  		*/  		$vars = array('forum_row', 'row', 'subforums_row');  		extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_template_vars', compact($vars))); diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 551165c558..0edf9304a3 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2386,7 +2386,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data  	* @var	string	url					The "Return to topic" URL  	*  	* @since 3.1.0-a3 -	* @change 3.1.0-RC3 Added vars mode, subject, username, topic_type, +	* @changed 3.1.0-RC3 Added vars mode, subject, username, topic_type,  	*		poll, update_message, update_search_index  	*/  	$vars = array( diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index a54d753787..ff962075a8 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -2158,7 +2158,7 @@ function phpbb_get_max_setting_from_group(\phpbb\db\driver\driver_interface $db,  	}  	// Get maximum number of allowed recipients -	$sql = 'SELECT MIN(g.group_' . $setting . ') as min_setting, MAX(g.group_' . $setting . ') as max_setting +	$sql = 'SELECT MAX(g.group_' . $setting . ') as max_setting  		FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug  		WHERE ug.user_id = ' . (int) $user_id . '  			AND ug.user_pending = 0 @@ -2167,9 +2167,8 @@ function phpbb_get_max_setting_from_group(\phpbb\db\driver\driver_interface $db,  	$row = $db->sql_fetchrow($result);  	$db->sql_freeresult($result);  	$max_setting = (int) $row['max_setting']; -	$min_setting = (int) $row['min_setting']; -	return ($min_setting > 0) ? $max_setting : 0; +	return $max_setting;  }  /** diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 8e1a9007e3..3dd4b3c2e5 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -272,13 +272,15 @@ 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	sql_ary		Array of data to be inserted when a user is added +	* @var array	user_row			Array of user details submited to user_add +	* @var array	cp_data				Array of Custom profile fields submited to user_add +	* @var array	sql_ary				Array of data to be inserted when a user is added +	* @var array	notifications_data	Array of notification data to be inserted when a user is added  	* @since 3.1.0-a1 -	* @change 3.1.0-b5 +	* @changed 3.1.0-b5 Added user_row and cp_data +	* @changed 3.1.11-RC1 Added notifications_data  	*/ -	$vars = array('user_row', 'cp_data', 'sql_ary'); +	$vars = array('user_row', 'cp_data', 'sql_ary', 'notifications_data');  	extract($phpbb_dispatcher->trigger_event('core.user_add_modify_data', compact($vars)));  	$sql = 'INSERT INTO ' . USERS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index c8e1e46209..3e214797c8 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -466,7 +466,7 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id)  		return;  	} -	$redirect = $request->variable('redirect', build_url(array('quickmod'))); +	$redirect = $request->variable('redirect', "{$phpbb_root_path}mcp.$phpEx?f=$forum_id&i=main&mode=forum_view");  	$s_hidden_fields = build_hidden_fields(array(  		'i'				=> 'main', diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 5786aa343a..971982e4fc 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -164,7 +164,7 @@ class mcp_main  				* @var	string	action		Topic quick moderation action name  				* @var	bool	quickmod	Flag indicating whether MCP is in quick moderation mode  				* @since 3.1.0-a4 -				* @change 3.1.0-RC4 Added variables: action, quickmod +				* @changed 3.1.0-RC4 Added variables: action, quickmod  				*/  				$vars = array('action', 'quickmod');  				extract($phpbb_dispatcher->trigger_event('core.modify_quickmod_actions', compact($vars))); diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 9060cc1098..f379392b12 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -577,7 +577,7 @@ class mcp_queue  						'POST_SUBJECT'	=> ($row['post_subject'] != '') ? $row['post_subject'] : $user->lang['NO_SUBJECT'],  						'TOPIC_TITLE'	=> $row['topic_title'],  						'POST_TIME'		=> $user->format_date($row['post_time']), -						'ATTACH_ICON_IMG'	=> ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && $row['post_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '', +						'S_HAS_ATTACHMENTS'	=> $auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && $row['post_attachment'],  					));  				}  				unset($rowset, $forum_names); diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index c68ff87cd7..d6e36fec39 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -1219,7 +1219,7 @@ class parse_message extends bbcode_firstpass  		* @var bool		return					Do we return after the event is triggered if $warn_msg is not empty  		* @var array	warn_msg				Array of the warning messages  		* @since 3.1.2-RC1 -		* @change 3.1.3-RC1 Added vars $bbcode_bitfield and $bbcode_uid +		* @changed 3.1.3-RC1 Added vars $bbcode_bitfield and $bbcode_uid  		*/  		$message = $this->message;  		$warn_msg = $this->warn_msg; diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index b61a9fab9f..06f76aa01a 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -280,7 +280,7 @@ function compose_pm($id, $mode, $action, $user_folders = array())  		* @var	bool	delete					Whether the user is deleting the PM  		* @var	int		reply_to_all			Value of reply_to_all request variable.  		* @since 3.1.0-RC5 -		* @change 3.2.0-a1 Removed undefined variables +		* @changed 3.2.0-a1 Removed undefined variables  		*/  		$vars = array(  			'sql', @@ -345,7 +345,7 @@ function compose_pm($id, $mode, $action, $user_folders = array())  			* @var	bool	delete				If deleting message  			* @var	int		reply_to_all		Value of reply_to_all request variable.  			* @since 3.1.0-RC5 -			* @change 3.2.0-a1 Removed undefined variables +			* @changed 3.2.0-a1 Removed undefined variables  			*/  			$vars = array(  				'sql', @@ -889,13 +889,8 @@ function compose_pm($id, $mode, $action, $user_folders = array())  		// Signature  		if ($enable_sig && $config['allow_sig'] && $preview_signature)  		{ -			$parse_sig = new parse_message($preview_signature); -			$parse_sig->bbcode_uid = $preview_signature_uid; -			$parse_sig->bbcode_bitfield = $preview_signature_bitfield; - -			$parse_sig->format_display($config['allow_sig_bbcode'], $config['allow_sig_links'], $config['allow_sig_smilies']); -			$preview_signature = $parse_sig->message; -			unset($parse_sig); +			$bbcode_flags = ($enable_bbcode ? OPTION_FLAG_BBCODE : 0) + ($enable_smilies ? OPTION_FLAG_SMILIES : 0) + ($enable_urls ? OPTION_FLAG_LINKS : 0); +			$preview_signature = generate_text_for_display($preview_signature, $preview_signature_uid, $preview_signature_bitfield, $bbcode_flags);  		}  		else  		{ diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index a06d1bd0a6..b5bb406d7d 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -545,7 +545,7 @@ function get_pm_from($folder_id, $folder, $user_id)  			AND $folder_sql  			AND t.msg_id = p.msg_id  			$sql_limit_time", -		'ORDER'	=> $sql_sort_order, +		'ORDER_BY'	=> $sql_sort_order,  	);  	/** diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 41dcba0387..b7f8501fe4 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -478,7 +478,9 @@ class ucp_profile  				$enable_smilies	= ($config['allow_sig_smilies']) ? $user->optionget('sig_smilies') : false;  				$enable_urls	= ($config['allow_sig_links']) ? $user->optionget('sig_links') : false; -				$decoded_message	= generate_text_for_edit($user->data['user_sig'], $user->data['user_sig_bbcode_uid'], $user->data['user_sig_bbcode_bitfield']); +				$bbcode_flags = ($enable_bbcode ? OPTION_FLAG_BBCODE : 0) + ($enable_smilies ? OPTION_FLAG_SMILIES : 0) + ($enable_urls ? OPTION_FLAG_LINKS : 0); + +				$decoded_message	= generate_text_for_edit($user->data['user_sig'], $user->data['user_sig_bbcode_uid'], $bbcode_flags);  				$signature			= $request->variable('signature', $decoded_message['text'], true);  				$signature_preview	= ''; @@ -506,7 +508,7 @@ class ucp_profile  				* @var	bool	submit				Whether or not the form has been sumitted  				* @var	bool	preview				Whether or not the signature is being previewed  				* @since 3.1.10-RC1 -				* @change 3.2.0-RC2 Removed message parser +				* @changed 3.2.0-RC2 Removed message parser  				*/  				$vars = array(  					'enable_bbcode', diff --git a/phpBB/install/app.php b/phpBB/install/app.php index 9664f92cf1..ef59689a65 100644 --- a/phpBB/install/app.php +++ b/phpBB/install/app.php @@ -20,6 +20,11 @@ define('PHPBB_ENVIRONMENT', 'production');  $phpbb_root_path = '../';  $phpEx = substr(strrchr(__FILE__, '.'), 1); +if (version_compare(PHP_VERSION, '5.4') < 0) +{ +	die('You are running an unsupported PHP version. Please upgrade to PHP 5.4.0 or higher before trying to install or update to phpBB 3.2'); +} +  $startup_new_path = $phpbb_root_path . 'install/update/update/new/install/startup.' . $phpEx;  $startup_path = (file_exists($startup_new_path)) ? $startup_new_path : $phpbb_root_path . 'install/startup.' . $phpEx;  require($startup_path); diff --git a/phpBB/install/convert/controller/convertor.php b/phpBB/install/convert/controller/convertor.php index 9a46117fe6..7b2a00d7b9 100644 --- a/phpBB/install/convert/controller/convertor.php +++ b/phpBB/install/convert/controller/convertor.php @@ -253,11 +253,11 @@ class convertor  	/**  	 * Obtain convertor settings  	 * -	 * @param string	$convertor	Name of the convertor +	 * @param string	$converter	Name of the convertor  	 *  	 * @return \Symfony\Component\HttpFoundation\Response|StreamedResponse  	 */ -	public function settings($convertor) +	public function settings($converter)  	{  		$this->setup_navigation('settings'); @@ -265,7 +265,7 @@ class convertor  		require_once ($this->phpbb_root_path . 'includes/functions_convert.' . $this->php_ext);  		// Include convertor if available -		$convertor_file_path = $this->phpbb_root_path . 'install/convertors/convert_' . $convertor . '.' . $this->php_ext; +		$convertor_file_path = $this->phpbb_root_path . 'install/convertors/convert_' . $converter . '.' . $this->php_ext;  		if (!file_exists($convertor_file_path))  		{  			if ($this->request->is_ajax()) @@ -313,8 +313,8 @@ class convertor  			// It must be an AJAX request at this point  			$response = new StreamedResponse();  			$ref = $this; -			$response->setCallback(function() use ($ref, $convertor) { -				$ref->proccess_settings_form($convertor); +			$response->setCallback(function() use ($ref, $converter) { +				$ref->proccess_settings_form($converter);  			});  			$response->headers->set('X-Accel-Buffering', 'no'); @@ -324,7 +324,7 @@ class convertor  		{  			$this->template->assign_vars(array(  				'U_ACTION'	=> $this->controller_helper->route('phpbb_convert_settings', array( -					'convertor'	=> $convertor, +					'converter'	=> $converter,  				))  			)); @@ -760,7 +760,7 @@ class convertor  				'SOFTWARE'	=> $convertors[$index]['forum_name'],  				'VERSION'	=> $convertors[$index]['version'], -				'U_CONVERT'	=> $this->controller_helper->route('phpbb_convert_settings', array('convertor' => $convertors[$index]['tag'])), +				'U_CONVERT'	=> $this->controller_helper->route('phpbb_convert_settings', array('converter' => $convertors[$index]['tag'])),  			));  		} diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index c7006f9758..73d4b6b1ff 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -38,7 +38,7 @@ $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);  $convertor_data = array(  	'forum_name'	=> 'phpBB 2.0.x',  	'version'		=> '1.0.3', -	'phpbb_version'	=> '3.2.0-RC3-dev', +	'phpbb_version'	=> '3.2.0',  	'author'		=> '<a href="https://www.phpbb.com/">phpBB Limited</a>',  	'dbms'			=> $dbms,  	'dbhost'		=> $dbhost, diff --git a/phpBB/install/phpbbcli.php b/phpBB/install/phpbbcli.php index f5dfa83712..c67766e8a1 100755 --- a/phpBB/install/phpbbcli.php +++ b/phpBB/install/phpbbcli.php @@ -23,7 +23,7 @@ if (php_sapi_name() !== 'cli')  define('IN_PHPBB', true);  define('IN_INSTALL', true);  define('PHPBB_ENVIRONMENT', 'production'); -define('PHPBB_VERSION', '3.2.0-RC3-dev'); +define('PHPBB_VERSION', '3.2.0');  $phpbb_root_path = __DIR__ . '/../';  $phpEx = substr(strrchr(__FILE__, '.'), 1); diff --git a/phpBB/install/phpinfo.php b/phpBB/install/phpinfo.php new file mode 100644 index 0000000000..28c3b9ff04 --- /dev/null +++ b/phpBB/install/phpinfo.php @@ -0,0 +1,14 @@ +<?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. + * + */ + +phpinfo(); diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 64397904e9..998cf17c3d 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -278,7 +278,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0  INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.2.0-RC3-dev'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.2.1-dev');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400'); diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index e3d8e6742f..6a5a4158e3 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -161,6 +161,8 @@ $lang = array_merge($lang, array(  	'ACP_POST_SETTINGS_EXPLAIN'			=> 'Here you can set all default settings for posting.',  	'ALLOW_POST_LINKS'					=> 'Allow links in posts/private messages',  	'ALLOW_POST_LINKS_EXPLAIN'			=> 'If disallowed the <code>[URL]</code> BBCode tag and automatic/magic URLs are disabled.', +	'ALLOWED_SCHEMES_LINKS'				=> 'Allowed schemes in links', +	'ALLOWED_SCHEMES_LINKS_EXPLAIN'		=> 'Users can only post schemeless URLs or one of the comma-separated list of allowed schemes.',  	'ALLOW_POST_FLASH'					=> 'Allow use of <code>[FLASH]</code> BBCode tag in posts',  	'ALLOW_POST_FLASH_EXPLAIN'			=> 'If disallowed the <code>[FLASH]</code> BBCode tag is disabled in posts. Otherwise the permission system controls which users can use the <code>[FLASH]</code> BBCode tag.', @@ -350,6 +352,8 @@ $lang = array_merge($lang, array(  	'COOKIE_DOMAIN'				=> 'Cookie domain',  	'COOKIE_NAME'				=> 'Cookie name', +	'COOKIE_NOTICE'				=> 'Cookie notice', +	'COOKIE_NOTICE_EXPLAIN'		=> 'If enabled a cookie notice will be displayed to users when visiting your board. This might be required by law depending on the content of your board and enabled extensions.',  	'COOKIE_PATH'				=> 'Cookie path',  	'COOKIE_SECURE'				=> 'Cookie secure',  	'COOKIE_SECURE_EXPLAIN'		=> 'If your server is running via SSL set this to enabled else leave as disabled. Having this enabled and not running via SSL will result in server errors during redirects.', diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index acd9776dd7..ac2c9da84d 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -395,7 +395,7 @@ $lang = array_merge($lang, array(  	'NUMBER_USERS'		=> 'Number of users',  	'NUMBER_ORPHAN'		=> 'Orphan attachments', -	'PHP_VERSION_OLD'	=> 'The version of PHP on this server will no longer be supported by future versions of phpBB. %sDetails%s', +	'PHP_VERSION_OLD'	=> 'The version of PHP on this server (%1$s) will no longer be supported by future versions of phpBB. The minimum required version will be PHP %2$s. %3$sDetails%4$s',  	'POSTS_PER_DAY'		=> 'Posts per day', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index c66f728c06..a04a06331b 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -178,6 +178,9 @@ $lang = array_merge($lang, array(  	'CONTACT'				=> 'Contact',  	'CONTACT_USER'			=> 'Contact %s',  	'CONTACT_US'			=> 'Contact us', +	'COOKIE_CONSENT_INFO'	=> 'Learn more', +	'COOKIE_CONSENT_MSG'	=> 'This website uses cookies to ensure you get the best experience on our website.', +	'COOKIE_CONSENT_OK'		=> 'Got it!',  	'COOKIES_DELETED'		=> 'All board cookies successfully deleted.',  	'CURRENT_TIME'			=> 'It is currently %s', @@ -341,6 +344,7 @@ $lang = array_merge($lang, array(  	'INTERESTS'					=> 'Interests',  	'INVALID_DIGEST_CHALLENGE'	=> 'Invalid digest challenge.',  	'INVALID_EMAIL_LOG'			=> '<strong>%s</strong> possibly an invalid email address?', +	'INVALID_FEED_ATTACHMENTS'	=> 'The selected feed tried fetching attachments with invalid constraints.',  	'INVALID_PLURAL_RULE'		=> 'The chosen plural rule is invalid. Valid values are integers between 0 and 15.',  	'IP'						=> 'IP',  	'IP_BLACKLISTED'			=> 'Your IP %1$s has been blocked because it is blacklisted. For details please see <a href="%2$s">%2$s</a>.', diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php index 45ed51f641..c2e741c6a7 100644 --- a/phpBB/language/en/install.php +++ b/phpBB/language/en/install.php @@ -224,6 +224,7 @@ $lang = array_merge($lang, array(  	// Server data  	//  	// Form labels +	'UPGRADE_INSTRUCTIONS'			=> 'A new feature release <strong>%1$s</strong> is available. Please read <a href="%2$s" title="%2$s"><strong>the release announcement</strong></a> to learn about what it has to offer, and how to upgrade.',  	'SERVER_CONFIG'				=> 'Server configuration',  	'SCRIPT_PATH'				=> 'Script path',  	'SCRIPT_PATH_EXPLAIN'		=> 'The path where phpBB is located relative to the domain name, e.g. <samp>/phpBB3</samp>.', @@ -296,9 +297,10 @@ $lang = array_merge($lang, array(  	'TASK_CREATE_TABLES'				=> 'Creating tables',  	// Install data -	'TASK_ADD_BOTS'			=> 'Registering bots', -	'TASK_ADD_LANGUAGES'	=> 'Installing available languages', -	'TASK_ADD_MODULES'		=> 'Installing modules', +	'TASK_ADD_BOTS'				=> 'Registering bots', +	'TASK_ADD_LANGUAGES'		=> 'Installing available languages', +	'TASK_ADD_MODULES'			=> 'Installing modules', +	'TASK_CREATE_SEARCH_INDEX'	=> 'Creating search index',  	// Install finish tasks  	'TASK_INSTALL_EXTENSIONS'	=> 'Installing packaged extensions', diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php index fc7cc1a0b1..dbd83f1eb0 100644 --- a/phpBB/phpbb/auth/auth.php +++ b/phpBB/phpbb/auth/auth.php @@ -514,7 +514,7 @@ class auth  	*/  	function acl_clear_prefetch($user_id = false)  	{ -		global $db, $cache; +		global $db, $cache, $phpbb_dispatcher;  		// Rebuild options cache  		$cache->destroy('_role_cache'); @@ -553,6 +553,16 @@ class auth  			$where_sql";  		$db->sql_query($sql); +		/** +		* Event is triggered after user(s) permission settings cache has been cleared +		* +		* @event core.acl_clear_prefetch_after +		* @var	mixed	user_id	User ID(s) +		* @since 3.1.11-RC1 +		*/ +		$vars = array('user_id'); +		extract($phpbb_dispatcher->trigger_event('core.acl_clear_prefetch_after', compact($vars))); +  		return;  	} diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index a210d877f0..497f00c06b 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -608,6 +608,6 @@ class file extends \phpbb\cache\driver\base  	*/  	protected function clean_varname($varname)  	{ -		return str_replace('/', '-', $varname); +		return str_replace(array('/', '\\'), '-', $varname);  	}  } diff --git a/phpBB/phpbb/db/migration/data/v320/cookie_notice.php b/phpBB/phpbb/db/migration/data/v320/cookie_notice.php new file mode 100644 index 0000000000..75cb03b3ef --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/cookie_notice.php @@ -0,0 +1,31 @@ +<?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\v320; + +class cookie_notice extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v320\v320rc2', +		); +	} + +	public function update_data() +	{ +		return array( +			array('config.add', array('cookie_notice', false)), +		); +	} +} diff --git a/phpBB/phpbb/db/migration/data/v320/v320.php b/phpBB/phpbb/db/migration/data/v320/v320.php new file mode 100644 index 0000000000..20e741cb8b --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320.php @@ -0,0 +1,40 @@ +<?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\v320; + +use phpbb\db\migration\migration; + +class v320 extends migration +{ +	public function effectively_installed() +	{ +		return version_compare($this->config['version'], '3.2.0', '>='); +	} + +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v31x\increase_size_of_emotion', +			'\phpbb\db\migration\data\v320\cookie_notice', +		); + +	} + +	public function update_data() +	{ +		return array( +			array('config.update', array('version', '3.2.0')), +		); +	} +} diff --git a/phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php b/phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php new file mode 100644 index 0000000000..1a83175705 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php @@ -0,0 +1,36 @@ +<?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 cookie_notice_p2 extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v320\v320', +		); +	} + +	public function effectively_installed() +	{ +		return isset($this->config['cookie_notice']); +	} + +	public function update_data() +	{ +		return array( +			array('config.add', array('cookie_notice', '0')), +		); +	} +} diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php new file mode 100644 index 0000000000..4d1b91f7b4 --- /dev/null +++ b/phpBB/phpbb/db/tools.php @@ -0,0 +1,21 @@ +<?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; + +/** + * @deprecated	3.2.0-dev	(To be removed 3.3.0) use \phpbb\db\tools\tools instead + */ +class tools extends \phpbb\db\tools\tools +{ +} diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index a132832005..d31aa2ba0b 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -477,7 +477,7 @@ class mssql extends tools  	{  		$statements = array(); -		$statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; +		$statements[] = 'DROP INDEX [' . $table_name . '].[' . $index_name . ']';  		return $this->_sql_run_sql($statements);  	} @@ -524,7 +524,10 @@ class mssql extends tools  	{  		$statements = array(); -		$this->check_index_name_length($table_name, $index_name); +		if ($this->is_sql_server_2000()) +		{ +			$this->check_index_name_length($table_name, $index_name); +		}  		$statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; @@ -538,7 +541,10 @@ class mssql extends tools  	{  		$statements = array(); -		$this->check_index_name_length($table_name, $index_name); +		if ($this->is_sql_server_2000()) +		{ +			$this->check_index_name_length($table_name, $index_name); +		}  		// remove index length  		$column = preg_replace('#:.*$#', '', $column); @@ -601,7 +607,7 @@ class mssql extends tools  		// Change the column  		$statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; -		if (!empty($column_data['default'])) +		if (!empty($column_data['default']) && !$this->mssql_is_column_identity($table_name, $column_name))  		{  			// Add new default value constraint  			$statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $column_data['default'] . ' FOR [' . $column_name . ']'; @@ -679,6 +685,37 @@ class mssql extends tools  	}  	/** +	 * Checks to see if column is an identity column +	 * +	 * Identity columns cannot have defaults set for them. +	 * +	 * @param string $table_name +	 * @param string $column_name +	 * @return bool		true if identity, false if not +	 */ +	protected function mssql_is_column_identity($table_name, $column_name) +	{ +		if ($this->mssql_is_sql_server_2000()) +		{ +			// http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx +			// Deprecated in SQL Server 2005 +			$sql = "SELECT COLUMNPROPERTY(object_id('{$table_name}'), '{$column_name}', 'IsIdentity') AS is_identity"; +		} +		else +		{ +			$sql = "SELECT is_identity FROM sys.columns +					WHERE object_id = object_id('{$table_name}') +					AND name = '{$column_name}'"; +		} + +		$result = $this->db->sql_query($sql); +		$is_identity = $this->db->sql_fetchfield('is_identity'); +		$this->db->sql_freeresult($result); + +		return (bool) $is_identity; +	} + +	/**  	* Get a list with existing indexes for the column  	*  	* @param string $table_name @@ -717,6 +754,7 @@ class mssql extends tools  						AND cols.object_id = ix.object_id  				WHERE ix.object_id = object_id('{$table_name}')  					AND cols.name = '{$column_name}' +					AND ix.is_primary_key = 0  					AND ix.is_unique = " . ($unique ? '1' : '0');  		} diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 4d5f189f12..ac1a1a1733 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -51,6 +51,11 @@ class container_builder  	protected $container;  	/** +	 * @var \phpbb\db\driver\driver_interface +	 */ +	protected $dbal_connection = null; + +	/**  	 * Indicates whether extensions should be used (default to true).  	 *  	 * @var bool @@ -197,6 +202,8 @@ class container_builder  				$this->container->set('config.php', $this->config_php_file);  			} +			$this->inject_dbal_driver(); +  			return $this->container;  		}  		catch (\Exception $e) @@ -511,7 +518,38 @@ class container_builder  		{  			$this->container->setParameter($key, $value);  		} +	} +	/** +	 * Inject the dbal connection driver into container +	 */ +	protected function inject_dbal_driver() +	{ +		if (empty($this->config_php_file)) +		{ +			return; +		} + +		$config_data = $this->config_php_file->get_all(); +		if (!empty($config_data)) +		{ +			if ($this->dbal_connection === null) +			{ +				$dbal_driver_class = $this->config_php_file->convert_30_dbms_to_31($this->config_php_file->get('dbms')); +				/** @var \phpbb\db\driver\driver_interface $dbal_connection */ +				$this->dbal_connection = new $dbal_driver_class(); +				$this->dbal_connection->sql_connect( +					$this->config_php_file->get('dbhost'), +					$this->config_php_file->get('dbuser'), +					$this->config_php_file->get('dbpasswd'), +					$this->config_php_file->get('dbname'), +					$this->config_php_file->get('dbport'), +					false, +					defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK +				); +			} +			$this->container->set('dbal.conn.driver', $this->dbal_connection); +		}  	}  	/** diff --git a/phpBB/phpbb/di/extension/config.php b/phpBB/phpbb/di/extension/config.php index 7984a783df..8c9de48823 100644 --- a/phpBB/phpbb/di/extension/config.php +++ b/phpBB/phpbb/di/extension/config.php @@ -43,12 +43,6 @@ class config extends Extension  			'core.adm_relative_path'	=> $this->config_php->get('phpbb_adm_relative_path') ? $this->config_php->get('phpbb_adm_relative_path') : 'adm/',  			'core.table_prefix'			=> $this->config_php->get('table_prefix'),  			'cache.driver.class'		=> $this->convert_30_acm_type($this->config_php->get('acm_type')), -			'dbal.driver.class'			=> $this->config_php->convert_30_dbms_to_31($this->config_php->get('dbms')), -			'dbal.dbhost'				=> $this->config_php->get('dbhost'), -			'dbal.dbuser'				=> $this->config_php->get('dbuser'), -			'dbal.dbpasswd'				=> $this->config_php->get('dbpasswd'), -			'dbal.dbname'				=> $this->config_php->get('dbname'), -			'dbal.dbport'				=> $this->config_php->get('dbport'),  			'dbal.new_link'				=> defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK,  		);  		$parameter_bag = $container->getParameterBag(); diff --git a/phpBB/phpbb/di/proxy_instantiator.php b/phpBB/phpbb/di/proxy_instantiator.php index a388e82c0e..70295a3dec 100644 --- a/phpBB/phpbb/di/proxy_instantiator.php +++ b/phpBB/phpbb/di/proxy_instantiator.php @@ -13,8 +13,6 @@  namespace phpbb\di; -use bantu\IniGetWrapper\IniGetWrapper; -use phpbb\filesystem\filesystem;  use ProxyManager\Configuration;  use ProxyManager\Factory\LazyLoadingValueHolderFactory;  use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; @@ -45,11 +43,8 @@ class proxy_instantiator implements InstantiatorInterface  		// Prevent trying to write to system temp dir in case of open_basedir  		// restrictions being in effect -		$ini_wrapper = new IniGetWrapper(); -		$filesystem = new filesystem();  		$tmp_dir = (function_exists('sys_get_temp_dir')) ? sys_get_temp_dir() : ''; -		if (empty($tmp_dir) || $ini_wrapper->getString('open_basedir') && -			(!$filesystem->exists($tmp_dir) || !$filesystem->is_writable($tmp_dir))) +		if (empty($tmp_dir) || !@file_exists($tmp_dir) || !@is_writable($tmp_dir))  		{  			$config->setProxiesTargetDir($cache_dir);  		} diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php index d2ab0595c0..ae3553c558 100644 --- a/phpBB/phpbb/event/php_exporter.php +++ b/phpBB/phpbb/event/php_exporter.php @@ -510,7 +510,7 @@ class php_exporter  	/**  	* Find the "@changed" Information lines  	* -	* @param string $tag_name Should be 'changed' or 'change' +	* @param string $tag_name Should be 'change', not 'changed'  	* @return array Absolute line numbers  	* @throws \LogicException  	*/ @@ -658,7 +658,7 @@ class php_exporter  	{  		$match = array();  		$line = str_replace("\t", ' ', ltrim($line, "\t ")); -		preg_match('#^\* @change(d)? (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)( (?:.*))?$#', $line, $match); +		preg_match('#^\* @changed (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)( (?:.*))?$#', $line, $match);  		if (!isset($match[2]))  		{  			throw new \LogicException("Invalid '@changed' information for event " diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index b2b60aaa9b..ca0ff31d5d 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -589,7 +589,7 @@ class manager  		$version_helper = new \phpbb\version_helper($this->cache, $this->config, new file_downloader());  		$version_helper->set_current_version($meta['version']); -		$version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename']); +		$version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename'], isset($version_check['ssl']) ? $version_check['ssl'] : false);  		$version_helper->force_stability($stability);  		return $updates = $version_helper->get_suggested_updates($force_update, $force_cache); diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 2b8b1bbd6a..ae1af10c1d 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -214,7 +214,20 @@ class metadata_manager  			case 'all':  				$this->validate('display'); -				$this->validate_enable(); +				if (!$this->validate_dir()) +				{ +					throw new \phpbb\extension\exception('EXTENSION_DIR_INVALID'); +				} + +				if (!$this->validate_require_phpbb()) +				{ +					throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('soft-require')); +				} + +				if (!$this->validate_require_php()) +				{ +					throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('require php')); +				}  			break;  			case 'display': diff --git a/phpBB/phpbb/feed/attachments_base.php b/phpBB/phpbb/feed/attachments_base.php index b14dafe15a..5d3272e0d9 100644 --- a/phpBB/phpbb/feed/attachments_base.php +++ b/phpBB/phpbb/feed/attachments_base.php @@ -25,8 +25,11 @@ abstract class attachments_base extends base  	/**  	* Retrieve the list of attachments that may be displayed +	* +	* @param array $post_ids Specify for which post IDs to fetch the attachments (optional) +	* @param array $topic_ids Specify for which topic IDs to fetch the attachments (optional)  	*/ -	protected function fetch_attachments() +	protected function fetch_attachments($post_ids = array(), $topic_ids = array())  	{  		$sql_array = array(  			'SELECT'   => 'a.*', @@ -37,7 +40,20 @@ abstract class attachments_base extends base  			'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC',  		); -		if (isset($this->topic_id)) +		if (!empty($post_ids)) +		{ +			$sql_array['WHERE'] .= 'AND ' . $this->db->sql_in_set('a.post_msg_id', $post_ids); +		} +		else if (!empty($topic_ids)) +		{ +			if (isset($this->topic_id)) +			{ +				$topic_ids[] = $this->topic_id; +			} + +			$sql_array['WHERE'] .= 'AND ' . $this->db->sql_in_set('a.topic_id', $topic_ids); +		} +		else if (isset($this->topic_id))  		{  			$sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id;  		} @@ -51,6 +67,11 @@ abstract class attachments_base extends base  			);  			$sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id;  		} +		else +		{ +			// Do not allow querying the full attachments table +			throw new \RuntimeException($this->user->lang('INVALID_FEED_ATTACHMENTS')); +		}  		$sql = $this->db->sql_build_query('SELECT', $sql_array);  		$result = $this->db->sql_query($sql); @@ -64,15 +85,6 @@ abstract class attachments_base extends base  	}  	/** -	* {@inheritDoc} -	*/ -	public function open() -	{ -		parent::open(); -		$this->fetch_attachments(); -	} - -	/**  	* Get attachments related to a given post  	*  	* @param $post_id  int  Post id diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php index f522e91169..0c142e8cc8 100644 --- a/phpBB/phpbb/feed/forum.php +++ b/phpBB/phpbb/feed/forum.php @@ -138,6 +138,8 @@ class forum extends post_base  			return false;  		} +		parent::fetch_attachments(array(), $topic_ids); +  		$this->sql = array(  			'SELECT'	=>	'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .  				'u.username, u.user_id', diff --git a/phpBB/phpbb/feed/news.php b/phpBB/phpbb/feed/news.php index fb6fa09278..13ca82c093 100644 --- a/phpBB/phpbb/feed/news.php +++ b/phpBB/phpbb/feed/news.php @@ -90,6 +90,8 @@ class news extends topic_base  			return false;  		} +		parent::fetch_attachments($post_ids); +  		$this->sql = array(  			'SELECT'	=> 'f.forum_id, f.forum_name,  							t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time, diff --git a/phpBB/phpbb/feed/overall.php b/phpBB/phpbb/feed/overall.php index 40cf94ace0..b083df922d 100644 --- a/phpBB/phpbb/feed/overall.php +++ b/phpBB/phpbb/feed/overall.php @@ -55,6 +55,8 @@ class overall extends post_base  			return false;  		} +		parent::fetch_attachments(array(), $topic_ids); +  		// Get the actual data  		$this->sql = array(  			'SELECT'	=>	'f.forum_id, f.forum_name, ' . diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php index e5f2c41468..2504e411b1 100644 --- a/phpBB/phpbb/feed/topic.php +++ b/phpBB/phpbb/feed/topic.php @@ -126,6 +126,8 @@ class topic extends post_base  	 */  	protected function get_sql()  	{ +		parent::fetch_attachments(); +  		$this->sql = array(  			'SELECT'	=>	'p.post_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .  				'u.username, u.user_id', diff --git a/phpBB/phpbb/feed/topics.php b/phpBB/phpbb/feed/topics.php index cf4a2e579e..183c29d11c 100644 --- a/phpBB/phpbb/feed/topics.php +++ b/phpBB/phpbb/feed/topics.php @@ -58,6 +58,8 @@ class topics extends topic_base  			return false;  		} +		parent::fetch_attachments($post_ids); +  		$this->sql = array(  			'SELECT'	=> 'f.forum_id, f.forum_name,  							t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time, diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php index 52340dc2d5..7ae0bde56b 100644 --- a/phpBB/phpbb/feed/topics_active.php +++ b/phpBB/phpbb/feed/topics_active.php @@ -77,6 +77,8 @@ class topics_active extends topic_base  			return false;  		} +		parent::fetch_attachments($post_ids); +  		$this->sql = array(  			'SELECT'	=> 'f.forum_id, f.forum_name,  							t.topic_id, t.topic_title, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, diff --git a/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php index 258a035768..5cdc331cbc 100644 --- a/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php +++ b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php @@ -47,7 +47,7 @@ class ftp_file_updater implements file_updater_interface  	 * @param string		$phpbb_root_path  	 * @param string		$php_ext  	 */ -	public function __constructor(update_helper $update_helper, $phpbb_root_path, $php_ext) +	public function __construct(update_helper $update_helper, $phpbb_root_path, $php_ext)  	{  		$this->transfer			= null;  		$this->update_helper	= $update_helper; diff --git a/phpBB/phpbb/install/module/install_data/task/create_search_index.php b/phpBB/phpbb/install/module/install_data/task/create_search_index.php new file mode 100644 index 0000000000..8a2f6aa1de --- /dev/null +++ b/phpBB/phpbb/install/module/install_data/task/create_search_index.php @@ -0,0 +1,134 @@ +<?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\install\module\install_data\task; + +use phpbb\auth\auth; +use phpbb\db\driver\driver_interface; +use phpbb\event\dispatcher; +use phpbb\config\config; +use phpbb\install\helper\container_factory; +use phpbb\language\language; +use phpbb\search\fulltext_native; +use phpbb\user; + +class create_search_index extends \phpbb\install\task_base +{ +	/** +	 * @var auth +	 */ +	protected $auth; + +	/** +	 * @var config +	 */ +	protected $config; + +	/** +	 * @var driver_interface +	 */ +	protected $db; + +	/** +	 * @var dispatcher +	 */ +	protected $phpbb_dispatcher; + +	/** +	 * @var language +	 */ +	protected $language; + +	/** +	 * @var user +	 */ +	protected $user; + +	/** +	 * @var string phpBB root path +	 */ +	protected $phpbb_root_path; + +	/** +	 * @var string PHP file extension +	 */ +	protected $php_ext; + +	/** +	 * Constructor +	 * +	 * @param config				$config				phpBB config +	 * @param container_factory		$container			Installer's DI container +	 * @param string				$phpbb_root_path	phpBB root path +	 * @param string				$php_ext			PHP file extension +	 */ +	public function __construct(config $config, container_factory $container, +								$phpbb_root_path, $php_ext) +	{ +		$this->auth				= $container->get('auth'); +		$this->config			= $config; +		$this->db				= $container->get('dbal.conn'); +		$this->language			= $container->get('language'); +		$this->phpbb_dispatcher = $container->get('dispatcher'); +		$this->user 			= $container->get('user'); + +		parent::__construct(true); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function run() +	{ +		// Make sure fulltext native load update is set +		$this->config->set('fulltext_native_load_upd', 1); + +		$error = false; +		$search = new fulltext_native( +			$error, +			$this->phpbb_root_path, +			$this->php_ext, +			$this->auth, +			$this->config, +			$this->db, +			$this->user, +			$this->phpbb_dispatcher +		); + +		$sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id +			FROM ' . POSTS_TABLE; +		$result = $this->db->sql_query($sql); + +		while ($row = $this->db->sql_fetchrow($result)) +		{ +			$search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']); +		} +		$this->db->sql_freeresult($result); +	} + +	/** +	 * {@inheritdoc} +	 */ +	static public function get_step_count() +	{ +		return 1; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function get_task_lang_name() +	{ +		return 'TASK_CREATE_SEARCH_INDEX'; +	} +} diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php index 1cb4f04297..e8a9c971b7 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php @@ -84,7 +84,7 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta  			$email_form = array(  				'email_enable' => array(  					'label'			=> 'ENABLE_EMAIL', -					'description'	=> 'COOKIE_SECURE_EXPLAIN', +					'description'	=> 'ENABLE_EMAIL_EXPLAIN',  					'type'			=> 'radio',  					'options'		=> array(  						array( diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 13c1591dcd..b66847b243 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -138,7 +138,7 @@ class update_extensions extends task_base  			$default_update_extensions = [];  			foreach (self::$default_extensions_update as $version => $extensions)  			{ -				if ($this->update_helper->phpbb_version_compare($version_from, $version, '<=')) +				if ($this->update_helper->phpbb_version_compare($version_from, $version, '<'))  				{  					$default_update_extensions = array_merge($default_update_extensions, $extensions);  				} 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 e3e6db6263..1792a3b723 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php @@ -132,41 +132,62 @@ class diff_files extends task_base  			$file_contents = array();  			// Handle the special case when user created a file with the filename that is now new in the core -			$file_contents[0] = (file_exists($old_path . $filename)) ? file_get_contents($old_path . $filename) : ''; +			if (file_exists($old_path . $filename)) +			{ +				$file_contents[0] = file_get_contents($old_path . $filename); -			$filenames = array( -				$this->phpbb_root_path . $filename, -				$new_path . $filename -			); +				$filenames = array( +					$this->phpbb_root_path . $filename, +					$new_path . $filename +				); -			foreach ($filenames as $file_to_diff) -			{ -				$file_contents[] = file_get_contents($file_to_diff); +				foreach ($filenames as $file_to_diff) +				{ +					$file_contents[] = file_get_contents($file_to_diff); + +					if ($file_contents[sizeof($file_contents) - 1] === false) +					{ +						$this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); +						unset($file_contents); +						throw new user_interaction_required_exception(); +					} +				} -				if ($file_contents[sizeof($file_contents) - 1] === false) +				$diff = new \diff3($file_contents[0], $file_contents[1], $file_contents[2]); +				unset($file_contents); + +				// Handle conflicts +				if ($diff->get_num_conflicts() !== 0)  				{ -					$this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); -					unset($file_contents); -					throw new user_interaction_required_exception(); +					$merge_conflicts[] = $filename;  				} -			} -			$diff = new \diff3($file_contents[0], $file_contents[1], $file_contents[2]); -			unset($file_contents); +				// Save merged output +				$this->cache->put( +					'_file_' . md5($filename), +					base64_encode(implode("\n", $diff->merged_output())) +				); -			// Handle conflicts -			if ($diff->get_num_conflicts() !== 0) -			{ -				$merge_conflicts[] = $filename; +				unset($diff);  			} +			else +			{ +				$new_file_content = file_get_contents($new_path . $filename); -			// Save merged output -			$this->cache->put( -				'_file_' . md5($filename), -				base64_encode(implode("\n", $diff->merged_output())) -			); +				if ($new_file_content === false) +				{ +					$this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); +					unset($new_file_content ); +					throw new user_interaction_required_exception(); +				} -			unset($diff); +				// Save new file content to cache +				$this->cache->put( +					'_file_' . md5($filename), +					base64_encode($new_file_content) +				); +				unset($new_file_content); +			}  			$progress_count++;  			$this->iohandler->set_progress('UPDATE_FILE_DIFF', $progress_count); diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index 5b48350e73..47a71eb844 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -123,7 +123,7 @@ class file_check extends task_base  		$default_update_extensions = [];  		foreach (\phpbb\install\module\update_database\task\update_extensions::$default_extensions_update as $version => $extensions)  		{ -			if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '>')) +			if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '>='))  			{  				$default_update_extensions = array_merge($default_update_extensions, $extensions);  			} diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index b9afc6d70a..03221e7c7a 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -456,6 +456,12 @@ class post extends \phpbb\notification\type\base  			return array();  		} -		return array('notification_data' => $serialized_data); +		$data_array = array_merge(array( +			'post_time'		=> $post['post_time'], +			'post_id'		=> $post['post_id'], +			'topic_id'		=> $post['topic_id'] +		), $this->get_data(false)); + +		return $data_array;  	}  } diff --git a/phpBB/phpbb/pagination.php b/phpBB/phpbb/pagination.php index 7a81c25ad2..a5a95b096d 100644 --- a/phpBB/phpbb/pagination.php +++ b/phpBB/phpbb/pagination.php @@ -284,7 +284,7 @@ class pagination  	*/  	public function get_on_page($per_page, $start)  	{ -		return floor($start / $per_page) + 1; +		return floor((int) $start / (int) $per_page) + 1;  	}  	/** diff --git a/phpBB/phpbb/profilefields/type/type_date.php b/phpBB/phpbb/profilefields/type/type_date.php index 414484920b..139ceabeec 100644 --- a/phpBB/phpbb/profilefields/type/type_date.php +++ b/phpBB/phpbb/profilefields/type/type_date.php @@ -72,7 +72,7 @@ class type_date extends type_base  			'lang_options'			=> $field_data['lang_options'],  		); -		$always_now = $request->variable('always_now', -1); +		$always_now = $this->request->variable('always_now', -1);  		if ($always_now == -1)  		{  			$s_checked = ($field_data['field_default_value'] == 'now') ? true : false; diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index 73d7bc1574..d5165df016 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -942,38 +942,45 @@ class fulltext_mysql extends \phpbb\search\base  			$this->get_stats();  		} -		$alter = array(); +		$alter_list = array();  		if (!isset($this->stats['post_subject']))  		{ +			$alter_entry = array();  			if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))  			{ -				$alter[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL'; +				$alter_entry[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL';  			}  			else  			{ -				$alter[] = 'MODIFY post_subject text NOT NULL'; +				$alter_entry[] = 'MODIFY post_subject text NOT NULL';  			} -			$alter[] = 'ADD FULLTEXT (post_subject)'; +			$alter_entry[] = 'ADD FULLTEXT (post_subject)'; +			$alter_list[] = $alter_entry;  		}  		if (!isset($this->stats['post_content']))  		{ +			$alter_entry = array();  			if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))  			{ -				$alter[] = 'MODIFY post_text mediumtext COLLATE utf8_unicode_ci NOT NULL'; +				$alter_entry[] = 'MODIFY post_text mediumtext COLLATE utf8_unicode_ci NOT NULL';  			}  			else  			{ -				$alter[] = 'MODIFY post_text mediumtext NOT NULL'; +				$alter_entry[] = 'MODIFY post_text mediumtext NOT NULL';  			} -			$alter[] = 'ADD FULLTEXT post_content (post_text, post_subject)'; +			$alter_entry[] = 'ADD FULLTEXT post_content (post_text, post_subject)'; +			$alter_list[] = $alter_entry;  		} -		if (sizeof($alter)) +		if (sizeof($alter_list))  		{ -			$this->db->sql_query('ALTER TABLE ' . POSTS_TABLE . ' ' . implode(', ', $alter)); +			foreach ($alter_list as $alter) +			{ +				$this->db->sql_query('ALTER TABLE ' . POSTS_TABLE . ' ' . implode(', ', $alter)); +			}  		}  		$this->db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 2071a973e5..73dcfce9a5 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -120,7 +120,7 @@ class fulltext_native extends \phpbb\search\base  		$this->phpbb_dispatcher = $phpbb_dispatcher;  		$this->user = $user; -		$this->word_length = array('min' => $this->config['fulltext_native_min_chars'], 'max' => $this->config['fulltext_native_max_chars']); +		$this->word_length = array('min' => (int) $this->config['fulltext_native_min_chars'], 'max' => (int) $this->config['fulltext_native_max_chars']);  		/**  		* Load the UTF tools diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index cbe2f02851..cc200b1adc 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -838,7 +838,7 @@ class session  			$sql = 'SELECT COUNT(session_id) AS sessions  					FROM ' . SESSIONS_TABLE . '  					WHERE session_user_id = ' . (int) $this->data['user_id'] . ' -					AND session_time >= ' . (int) ($this->time_now - (max($config['session_length'], $config['form_token_lifetime']))); +					AND session_time >= ' . (int) ($this->time_now - (max((int) $config['session_length'], (int) $config['form_token_lifetime'])));  			$result = $db->sql_query($sql);  			$row = $db->sql_fetchrow($result);  			$db->sql_freeresult($result); diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php index 9a40702ba8..41c0a01ba8 100644 --- a/phpBB/phpbb/template/base.php +++ b/phpBB/phpbb/template/base.php @@ -133,6 +133,14 @@ abstract class base implements template  	}  	/** +	* {@inheritdoc} +	*/ +	public function find_key_index($blockname, $key) +	{ +		return $this->context->find_key_index($blockname, $key); +	} + +	/**  	* Calls hook if any is defined.  	*  	* @param string $handle Template handle being displayed. diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 4ee48205c8..c7df29d62c 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -264,6 +264,89 @@ class context  	}  	/** +	* Find the index for a specified key in the innermost specified block +	* +	* @param	string	$blockname	the blockname, for example 'loop' +	* @param	mixed	$key		Key to search for +	* +	* array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] +	* +	* int: Position [the position to search for] +	* +	* If key is false the position is set to 0 +	* If key is true the position is set to the last entry +	* +	* @return mixed false if not found, index position otherwise; be sure to test with === +	*/ +	public function find_key_index($blockname, $key) +	{ +		// For nested block, $blockcount > 0, for top-level block, $blockcount == 0 +		$blocks = explode('.', $blockname); +		$blockcount = sizeof($blocks) - 1; + +		$block = $this->tpldata; +		for ($i = 0; $i < $blockcount; $i++) +		{ +			if (($pos = strpos($blocks[$i], '[')) !== false) +			{ +				$name = substr($blocks[$i], 0, $pos); + +				if (strpos($blocks[$i], '[]') === $pos) +				{ +					$index = sizeof($block[$name]) - 1; +				} +				else +				{ +					$index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1); +				} +			} +			else +			{ +				$name = $blocks[$i]; +				$index = sizeof($block[$name]) - 1; +			} +			if (!isset($block[$name])) +			{ +				return false; +			} +			$block = $block[$name]; +			if (!isset($block[$index])) +			{ +				return false; +			} +			$block = $block[$index]; +		} + +		if (!isset($block[$blocks[$i]])) +		{ +			return false; +		} +		$block = $block[$blocks[$i]]; // Traverse the last block + +		// Change key to zero (change first position) if false and to last position if true +		if ($key === false || $key === true) +		{ +			return ($key === false) ? 0 : sizeof($block) - 1; +		} + +		// Get correct position if array given +		if (is_array($key)) +		{ +			// Search array to get correct position +			list($search_key, $search_value) = @each($key); +			foreach ($block as $i => $val_ary) +			{ +				if ($val_ary[$search_key] === $search_value) +				{ +					return $i; +				} +			} +		} + +		return (is_int($key) && ((0 <= $key) && ($key < sizeof($block)))) ? $key : false; +	} + +	/**  	* Change already assigned key variable pair (one-dimensional - single loop entry)  	*  	* An example of how to use this function: @@ -365,15 +448,15 @@ class context  		if ($mode == 'insert')  		{  			// Make sure we are not exceeding the last iteration -			if ($key >= sizeof($this->tpldata[$blockname])) +			if ($key >= sizeof($block))  			{ -				$key = sizeof($this->tpldata[$blockname]); -				unset($this->tpldata[$blockname][($key - 1)]['S_LAST_ROW']); +				$key = sizeof($block); +				unset($block[($key - 1)]['S_LAST_ROW']);  				$vararray['S_LAST_ROW'] = true;  			}  			else if ($key === 0)  			{ -				unset($this->tpldata[$blockname][0]['S_FIRST_ROW']); +				unset($block[0]['S_FIRST_ROW']);  				$vararray['S_FIRST_ROW'] = true;  			} diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php index 041ecb12e4..9e3d658ca8 100644 --- a/phpBB/phpbb/template/template.php +++ b/phpBB/phpbb/template/template.php @@ -173,6 +173,23 @@ interface template  	public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert');  	/** +	* Find the index for a specified key in the innermost specified block +	* +	* @param	string	$blockname	the blockname, for example 'loop' +	* @param	mixed	$key		Key to search for +	* +	* array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] +	* +	* int: Position [the position to search for] +	* +	* If key is false the position is set to 0 +	* If key is true the position is set to the last entry +	* +	* @return mixed false if not found, index position otherwise; be sure to test with === +	*/ +	public function find_key_index($blockname, $key); + +	/**  	* Get path to template for handle (required for BBCode parser)  	*  	* @param string $handle Handle to retrieve the source file diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 92f87a0331..f0e716d697 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -170,8 +170,7 @@ class extension extends \Twig_Extension  		$args = func_get_args();  		$key = $args[0]; -		$context = $this->context->get_data_ref(); -		$context_vars = $context['.'][0]; +		$context_vars = $this->context->get_root_ref();  		if (isset($context_vars['L_' . $key]))  		{ diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php index 2103bf8e60..0d37e62c87 100644 --- a/phpBB/phpbb/textformatter/data_access.php +++ b/phpBB/phpbb/textformatter/data_access.php @@ -81,11 +81,8 @@ class data_access  	public function get_bbcodes()  	{  		$sql = 'SELECT bbcode_match, bbcode_tpl FROM ' . $this->bbcodes_table; -		$result = $this->db->sql_query($sql); -		$rows = $this->db->sql_fetchrowset($result); -		$this->db->sql_freeresult($result); -		return $rows; +		return $this->fetch_decoded_rowset($sql, ['bbcode_match']);  	}  	/** @@ -101,11 +98,8 @@ class data_access  		$sql = 'SELECT code, emotion, smiley_url, smiley_width, smiley_height  			FROM ' . $this->smilies_table . '  			ORDER BY display_on_posting DESC'; -		$result = $this->db->sql_query($sql); -		$rows = $this->db->sql_fetchrowset($result); -		$this->db->sql_freeresult($result); -		return $rows; +		return $this->fetch_decoded_rowset($sql, ['code', 'emotion', 'smiley_url']);  	}  	/** @@ -116,11 +110,8 @@ class data_access  	protected function get_styles()  	{  		$sql = 'SELECT style_id, style_path, style_parent_id, bbcode_bitfield FROM ' . $this->styles_table; -		$result = $this->db->sql_query($sql); -		$rows = $this->db->sql_fetchrowset($result); -		$this->db->sql_freeresult($result); -		return $rows; +		return $this->fetch_decoded_rowset($sql);  	}  	/** @@ -219,10 +210,43 @@ class data_access  	public function get_censored_words()  	{  		$sql = 'SELECT word, replacement FROM ' . $this->words_table; + +		return $this->fetch_decoded_rowset($sql, ['word', 'replacement']); +	} + +	/** +	* Decode HTML special chars in given rowset +	* +	* @param  array $rows    Original rowset +	* @param  array $columns List of columns to decode +	* @return array          Decoded rowset +	*/ +	protected function decode_rowset(array $rows, array $columns) +	{ +		foreach ($rows as &$row) +		{ +			foreach ($columns as $column) +			{ +				$row[$column] = htmlspecialchars_decode($row[$column]); +			} +		} + +		return $rows; +	} + +	/** +	* Fetch all rows for given query and decode plain text columns +	* +	* @param  string $sql     SELECT query +	* @param  array  $columns List of columns to decode +	* @return array +	*/ +	protected function fetch_decoded_rowset($sql, array $columns = []) +	{  		$result = $this->db->sql_query($sql);  		$rows = $this->db->sql_fetchrowset($result);  		$this->db->sql_freeresult($result); -		return $rows; +		return $this->decode_rowset($rows, $columns);  	}  } diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index a310c67359..5cbf2712f7 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -333,8 +333,7 @@ class factory implements \phpbb\textformatter\cache_interface  			$configurator->plugins->load('Censor', array('tagName' => 'censor:tag'));  			foreach ($censor as $row)  			{ -				// NOTE: words are stored as HTML, we need to decode them to plain text -				$configurator->Censor->add(htmlspecialchars_decode($row['word']),  htmlspecialchars_decode($row['replacement'])); +				$configurator->Censor->add($row['word'], $row['replacement']);  			}  		} @@ -348,10 +347,10 @@ 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->setImageSize(18); +		$configurator->Emoji->omitImageSize();  		$configurator->Emoji->useSVG();  		$tag = $configurator->Emoji->getTag(); -		$tag->template = '<xsl:choose><xsl:when test="$S_VIEWSMILIES">' . str_replace('class="emoji"', 'class="smilies"', $tag->template) . '</xsl:when><xsl:otherwise><xsl:value-of select="."/></xsl:otherwise></xsl:choose>'; +		$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>';  		/**  		* Modify the s9e\TextFormatter configurator after the default settings are set diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index e2653d60f0..05ddfffa11 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -142,6 +142,7 @@ class parser implements \phpbb\textformatter\parser_interface  	public function disable_smilies()  	{  		$this->parser->disablePlugin('Emoticons'); +		$this->parser->disablePlugin('Emoji');  	}  	/** @@ -183,6 +184,7 @@ class parser implements \phpbb\textformatter\parser_interface  	public function enable_smilies()  	{  		$this->parser->enablePlugin('Emoticons'); +		$this->parser->enablePlugin('Emoji');  	}  	/** diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index b317fe4a8d..a9a6d4b892 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -136,4 +136,17 @@ class utils implements \phpbb\textformatter\utils_interface  	{  		return \s9e\TextFormatter\Unparser::unparse($xml);  	} + +	/** +	 * {@inheritdoc} +	 */ +	public function is_empty($text) +	{ +		if ($text === null || $text === '') +		{ +			return true; +		} + +		return trim($this->unparse($text)) === ''; +	}  } diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php index 4810453cd1..4b7392976a 100644 --- a/phpBB/phpbb/textformatter/utils_interface.php +++ b/phpBB/phpbb/textformatter/utils_interface.php @@ -62,10 +62,18 @@ interface utils_interface  	public function remove_bbcode($text, $bbcode_name, $depth = 0);  	/** -	* Return a parsed text to its original form -	* -	* @param  string $text Parsed text -	* @return string       Original plain text -	*/ +	 * Return a parsed text to its original form +	 * +	 * @param  string $text Parsed text +	 * @return string       Original plain text +	 */  	public function unparse($text); + +	/** +	 * Return whether or not a parsed text represent an empty text. +	 * +	 * @param  string $text Parsed text +	 * @return bool         Tue if the original text is empty +	 */ +	public function is_empty($text);  } diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index 17caaa4a60..f80d2b16fc 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -198,6 +198,49 @@ class version_helper  	}  	/** +	 * Gets the latest update for the current branch the user is on +	 * Will suggest versions from newer branches when EoL has been reached +	 * and/or version from newer branch is needed for having all known security +	 * issues fixed. +	 * +	 * @param bool $force_update Ignores cached data. Defaults to false. +	 * @param bool $force_cache Force the use of the cache. Override $force_update. +	 * @return array Version info or empty array if there are no updates +	 * @throws \RuntimeException +	 */ +	public function get_update_on_branch($force_update = false, $force_cache = false) +	{ +		$versions = $this->get_versions_matching_stability($force_update, $force_cache); + +		$self = $this; +		$current_version = $this->current_version; + +		// Filter out any versions less than to the current version +		$versions = array_filter($versions, function($data) use ($self, $current_version) { +			return $self->compare($data['current'], $current_version, '>='); +		}); + +		// Get the lowest version from the previous list. +		$update_info = array_reduce($versions, function($value, $data) use ($self, $current_version) { +			if ($value === null && $self->compare($data['current'], $current_version, '>=')) +			{ +				if (!$data['eol'] && (!$data['security'] || $self->compare($data['security'], $data['current'], '<='))) +				{ +					return ($self->compare($data['current'], $current_version, '>')) ? $data : array(); +				} +				else +				{ +					return null; +				} +			} + +			return $value; +		}); + +		return $update_info === null ? array() : $update_info; +	} + +	/**  	* Obtains the latest version information  	*  	* @param bool $force_update Ignores cached data. Defaults to false. diff --git a/phpBB/posting.php b/phpBB/posting.php index b0aef2482a..21783b070b 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -84,7 +84,7 @@ $current_time = time();  *							NOTE: Should be actual language strings, NOT  *							language keys.  * @since 3.1.0-a1 -* @change 3.1.2-RC1			Removed 'delete' var as it does not exist +* @changed 3.1.2-RC1			Removed 'delete' var as it does not exist  */  $vars = array(  	'post_id', @@ -816,6 +816,7 @@ if ($load && ($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $post_  	load_drafts($topic_id, $forum_id);  } +$bbcode_utils = $phpbb_container->get('text_formatter.utils');  if ($submit || $preview || $refresh)  { @@ -944,7 +945,9 @@ if ($submit || $preview || $refresh)  	*				is posting a new topic or editing a post)  	* @var	bool	refresh		Whether or not to retain previously submitted data  	* @var	object	message_parser	The message parser object +	* @var	array	error		Array of errors  	* @since 3.1.2-RC1 +	* @changed 3.1.11-RC1 Added error  	*/  	$vars = array(  		'post_data', @@ -959,6 +962,7 @@ if ($submit || $preview || $refresh)  		'cancel',  		'refresh',  		'message_parser', +		'error',  	);  	extract($phpbb_dispatcher->trigger_event('core.posting_modify_message_text', compact($vars))); @@ -1178,7 +1182,7 @@ if ($submit || $preview || $refresh)  		$post_data['poll_title'] = '';  		$post_data['poll_start'] = $post_data['poll_length'] = $post_data['poll_max_options'] = $post_data['poll_last_vote'] = $post_data['poll_vote_change'] = 0;  	} -	else if (!$auth->acl_get('f_poll', $forum_id) && ($mode == 'edit') && ($post_id == $post_data['topic_first_post_id']) && ($original_poll_data['poll_title'] != '')) +	else if (!$auth->acl_get('f_poll', $forum_id) && ($mode == 'edit') && ($post_id == $post_data['topic_first_post_id']) && !$bbcode_utils->is_empty($original_poll_data['poll_title']))  	{  		// We have a poll but the editing user is not permitted to create/edit it.  		// So we just keep the original poll-data. @@ -1266,8 +1270,8 @@ if ($submit || $preview || $refresh)  	* @var	array	error		Any error strings; a non-empty array aborts form submission.  	*				NOTE: Should be actual language strings, NOT language keys.  	* @since 3.1.0-RC5 -	* @change 3.1.5-RC1 Added poll array to the event -	* @change 3.2.0-a1 Removed undefined page_title +	* @changed 3.1.5-RC1 Added poll array to the event +	* @changed 3.2.0-a1 Removed undefined page_title  	*/  	$vars = array(  		'post_data', @@ -1601,7 +1605,7 @@ if ($generate_quote)  	if ($config['allow_bbcode'])  	{ -		$message_parser->message = $phpbb_container->get('text_formatter.utils')->generate_quote( +		$message_parser->message = $bbcode_utils->generate_quote(  			censor_text($message_parser->message),  			array(  				'author'  => $post_data['quote_username'], @@ -1639,7 +1643,7 @@ $attachment_data = $message_parser->attachment_data;  $filename_data = $message_parser->filename_data;  $post_data['post_text'] = $message_parser->message; -if (sizeof($post_data['poll_options']) || !empty($post_data['poll_title'])) +if (sizeof($post_data['poll_options']) || (isset($post_data['poll_title']) && !$bbcode_utils->is_empty($post_data['poll_title'])))  {  	$message_parser->message = $post_data['poll_title'];  	$message_parser->bbcode_uid = $post_data['bbcode_uid']; @@ -1884,13 +1888,13 @@ if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_  *				posting page via $template->assign_vars()  * @var	object	message_parser	The message parser object  * @since 3.1.0-a1 -* @change 3.1.0-b3 Added vars post_data, moderators, mode, page_title, +* @changed 3.1.0-b3 Added vars post_data, moderators, mode, page_title,  *		s_topic_icons, form_enctype, s_action, s_hidden_fields,  *		post_id, topic_id, forum_id, submit, preview, save, load,  *		delete, cancel, refresh, error, page_data, message_parser -* @change 3.1.2-RC1 Removed 'delete' var as it does not exist -* @change 3.1.5-RC1 Added poll variables to the page_data array -* @change 3.1.6-RC1 Added 'draft_id' var +* @changed 3.1.2-RC1 Removed 'delete' var as it does not exist +* @changed 3.1.5-RC1 Added poll variables to the page_data array +* @changed 3.1.6-RC1 Added 'draft_id' var  */  $vars = array(  	'post_data', diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg index 6701ce5905..725282036b 100644 --- a/phpBB/styles/prosilver/style.cfg +++ b/phpBB/styles/prosilver/style.cfg @@ -21,8 +21,8 @@  # General Information about this style  name = prosilver  copyright = © phpBB Limited, 2007 -style_version = 3.2.0-RC2 -phpbb_version = 3.2.0-RC2 +style_version = 3.2.0 +phpbb_version = 3.2.0  # Defining a different template bitfield  # template_bitfield = lNg= diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index b803a6f5c8..f1d423d269 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -57,7 +57,7 @@ function marklist(id, name, state) {  	jQuery('#' + id + ' input[type=checkbox][name]').each(function() {  		var $this = jQuery(this); -		if ($this.attr('name').substr(0, name.length) === name) { +		if ($this.attr('name').substr(0, name.length) === name && !$this.prop('disabled')) {  			$this.prop('checked', state);  		}  	}); diff --git a/phpBB/styles/prosilver/template/mcp_queue.html b/phpBB/styles/prosilver/template/mcp_queue.html index c82aae5f8c..ee69bf448d 100644 --- a/phpBB/styles/prosilver/template/mcp_queue.html +++ b/phpBB/styles/prosilver/template/mcp_queue.html @@ -48,7 +48,7 @@  			<dl>  				<dt>  					<div class="list-inner"> -						<a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.POST_SUBJECT}</a> <i class="icon fa-paperclip fa-fw" aria-hidden="true"></i> <br /> +						<a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.POST_SUBJECT}</a><!-- IF postrow.S_HAS_ATTACHMENTS --> <i class="icon fa-paperclip fa-fw" aria-hidden="true"></i> <!-- ENDIF --><br />  						<span>{L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} » {postrow.POST_TIME}</span>  					</div>  				</dt> diff --git a/phpBB/styles/prosilver/template/memberlist_team.html b/phpBB/styles/prosilver/template/memberlist_team.html index 63349064bb..59041fbac0 100644 --- a/phpBB/styles/prosilver/template/memberlist_team.html +++ b/phpBB/styles/prosilver/template/memberlist_team.html @@ -19,7 +19,7 @@  	<tbody>  <!-- BEGIN user -->  	<tr class="<!-- IF group.user.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF group.user.S_INACTIVE --> inactive<!-- ENDIF -->"> -		<td><!-- IF group.user.RANK_IMG --><span class="rank-img">{group.user.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{group.user.RANK_TITLE}</span><!-- ENDIF -->{group.user.USERNAME_FULL}<!-- IF group.user.S_INACTIVE --> ({L_INACTIVE})<!-- ENDIF --></td> +		<td><!-- IF group.user.RANK_IMG --><span class="rank-img">{group.user.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{group.user.RANK_TITLE}</span><!-- ENDIF --><!-- EVENT memberlist_team_username_prepend -->{group.user.USERNAME_FULL}<!-- IF group.user.S_INACTIVE --> ({L_INACTIVE})<!-- ENDIF --><!-- EVENT memberlist_team_username_append --></td>  		<td class="info"><!-- IF group.user.U_GROUP -->  			<a<!-- IF group.user.GROUP_COLOR --> style="font-weight: bold; color: #{group.user.GROUP_COLOR}"<!-- ENDIF --> href="{group.user.U_GROUP}">{group.user.GROUP_NAME}</a>  			<!-- ELSE --> diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 39468201e5..413c93f79a 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -59,6 +59,29 @@  	</script>  <!-- ENDIF --> +<!-- IF S_COOKIE_NOTICE --> +	<script src="{T_ASSETS_PATH}/cookieconsent/cookieconsent.min.js?assets_version={T_ASSETS_VERSION}"></script> +	<script> +		window.addEventListener("load", function(){ +			window.cookieconsent.initialise({ +				"palette": { +					"popup": { +						"background": "#0F538A" +					}, +					"button": { +						"background": "#E5E5E5" +					} +				}, +				"theme": "classic", +				"content": { +					"message": "{LA_COOKIE_CONSENT_MSG}", +					"dismiss": "{LA_COOKIE_CONSENT_OK}", +					"link": "{LA_COOKIE_CONSENT_INFO}" +				} +			})}); +	</script> +<!-- ENDIF --> +  <!-- EVENT overall_footer_after -->  <!-- IF S_PLUPLOAD --><!-- INCLUDE plupload.html --><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html index 4a31a0adde..4438137f7d 100644 --- a/phpBB/styles/prosilver/template/overall_header.html +++ b/phpBB/styles/prosilver/template/overall_header.html @@ -57,6 +57,10 @@  	<link href="{T_THEME_PATH}/plupload.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">  <!-- ENDIF --> +<!-- IF S_COOKIE_NOTICE --> +	<link href="{T_ASSETS_PATH}/cookieconsent/cookieconsent.min.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet"> +<!-- ENDIF --> +  <!--[if lte IE 9]>  	<link href="{T_THEME_PATH}/tweaks.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">  <![endif]--> diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index f7114567e5..6bbf9c9afe 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -78,7 +78,7 @@  			<!-- EVENT search_results_topic_before -->  			<li class="row<!-- IF searchresults.S_ROW_COUNT is even --> bg1<!-- ELSE --> bg2<!-- ENDIF -->">  				<dl class="row-item {searchresults.TOPIC_IMG_STYLE}"> -					<dt<!-- IF searchresults.TOPIC_ICON_IMG and S_TOPIC_ICONS --> style="background-image: url({T_ICONS_PATH}{searchresults.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{searchresults.TOPIC_FOLDER_IMG_ALT}"> +					<dt<!-- IF searchresults.TOPIC_ICON_IMG --> style="background-image: url({T_ICONS_PATH}{searchresults.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{searchresults.TOPIC_FOLDER_IMG_ALT}">  						<!-- IF searchresults.S_UNREAD_TOPIC and not S_IS_BOT --><a href="{searchresults.U_NEWEST_POST}" class="row-item-link"></a><!-- ENDIF -->  						<div class="list-inner">  							<!-- EVENT topiclist_row_prepend --> @@ -104,6 +104,7 @@  								</a>  							<!-- ENDIF -->  							<br /> +							<!-- EVENT topiclist_row_topic_title_after -->  							<!-- IF not S_IS_BOT -->  								<div class="responsive-show" style="display: none;"> @@ -134,7 +135,6 @@  								</ul>  							</div>  							<!-- ENDIF --> -							<!-- EVENT topiclist_row_topic_title_after -->  							<!-- EVENT topiclist_row_append -->  						</div> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index e2a086060c..4295867c05 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -15,7 +15,7 @@  		<!-- ENDIF -->  		<!-- IF U_VIEW_NEXT_HISTORY -->  			<a href="{U_VIEW_NEXT_HISTORY}" class="right-box arrow-{S_CONTENT_FLOW_END}"> -				<i class="icon fa-angle-{S_CONTENT_FLOW_BEGIN} fa-fw icon-black" aria-hidden="true"></i><span>{L_VIEW_NEXT_HISTORY}</span> +				<i class="icon fa-angle-{S_CONTENT_FLOW_END} fa-fw icon-black" aria-hidden="true"></i><span>{L_VIEW_NEXT_HISTORY}</span>  			</a>  		<!-- ENDIF -->  	</fieldset> @@ -179,7 +179,7 @@  	<!-- ENDIF -->  	<!-- IF U_NEXT_PM -->  		<a href="{U_NEXT_PM}" class="right-box arrow-{S_CONTENT_FLOW_END}"> -			<i class="icon fa-angle-{S_CONTENT_FLOW_BEGIN} fa-fw icon-black" aria-hidden="true"></i><span>{L_VIEW_NEXT_PM}</span> +			<i class="icon fa-angle-{S_CONTENT_FLOW_END} fa-fw icon-black" aria-hidden="true"></i><span>{L_VIEW_NEXT_PM}</span>  		</a>  	<!-- ENDIF -->  	<!-- IF not S_UNREAD and not S_SPECIAL_FOLDER --><label for="dest_folder"><!-- IF S_VIEW_MESSAGE -->{L_MOVE_TO_FOLDER}{L_COLON} <!-- ELSE -->{L_MOVE_MARKED_TO_FOLDER}<!-- ENDIF --> <select name="dest_folder" id="dest_folder">{S_TO_FOLDER_OPTIONS}</select></label> <input class="button2" type="submit" name="move_pm" value="{L_GO}" /><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index 9824989687..867fd84112 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -189,10 +189,12 @@  							{L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} « <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{topicrow.LAST_POST_TIME}</a>  							<!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --><br />{L_POSTED} {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF -->  						</div> -						<!-- IF topicrow.REPLIES --><span class="responsive-show left-box" style="display: none;">{L_REPLIES}{L_COLON} <strong>{topicrow.REPLIES}</strong></span><!-- ENDIF --> +							<!-- IF topicrow.REPLIES --> +							<span class="responsive-show" style="display: none;">{L_REPLIES}{L_COLON} <strong>{topicrow.REPLIES}</strong></span> +							<!-- ENDIF -->  						<!-- ENDIF --> -						<div class="responsive-hide"> +						<div class="topic-poster responsive-hide">  							<!-- IF topicrow.S_HAS_POLL --><i class="icon fa-bar-chart fa-fw" aria-hidden="true"></i><!-- ENDIF -->  							<!-- IF topicrow.ATTACH_ICON_IMG --><i class="icon fa-paperclip fa-fw" aria-hidden="true"></i><!-- ENDIF -->  							{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 9da5cfe3be..df9226e666 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -887,8 +887,8 @@ fieldset.fields1 dl.pmlist dd.recipients {  .row .pagination li a, .row .pagination li span {  	border-radius: 2px; -    padding: 1px 3px; -    font-size: 9px; +	padding: 1px 3px; +	font-size: 9px;  }  /* jQuery popups @@ -1047,6 +1047,13 @@ ul.linklist:after,  	display: block;  } +.emoji { +	min-height: 18px; +	min-width: 18px; +	height: 1em; +	width: 1em; +} +  .smilies {  	vertical-align: text-bottom;  } diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index 53beee621d..95168d1d97 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -134,15 +134,17 @@ li.header dl.row-item dt .list-inner {  dl.row-item {  	background-position: 10px 50%;		/* Position of folder icon */  	background-repeat: no-repeat; +	background-size: 32px;  }  dl.row-item dt {  	background-repeat: no-repeat;  	background-position: 5px 95%;		/* Position of topic icon */ +	background-size: 17px;  }  dl.row-item dt .list-inner { -	padding-left: 45px;					/* Space for folder icon */ +	padding-left: 52px;					/* Space for folder icon */  }  dl.row-item dt, dl.row-item dd { @@ -493,6 +495,8 @@ blockquote cite > div {  	border: 1px solid transparent;  	font-size: 1em;  	margin: 1em 0 1.2em 0; +	overflow-x: scroll; +	word-wrap: normal;  }  .codebox p { diff --git a/phpBB/styles/prosilver/theme/icons.css b/phpBB/styles/prosilver/theme/icons.css index 9fb7244f4b..411fecaf3b 100644 --- a/phpBB/styles/prosilver/theme/icons.css +++ b/phpBB/styles/prosilver/theme/icons.css @@ -54,6 +54,10 @@  	font-size: 16px;  } +.arrow-left .icon { +	float: left; +} +  .arrow-left:hover .icon {  	margin-left: -5px;  	margin-right: 5px; diff --git a/phpBB/styles/prosilver/theme/images/announce_read.gif b/phpBB/styles/prosilver/theme/images/announce_read.gifBinary files differ index 9457870e6f..b61cc54140 100644 --- a/phpBB/styles/prosilver/theme/images/announce_read.gif +++ b/phpBB/styles/prosilver/theme/images/announce_read.gif diff --git a/phpBB/styles/prosilver/theme/images/announce_read_locked.gif b/phpBB/styles/prosilver/theme/images/announce_read_locked.gifBinary files differ index 76ead8a02c..8c7393edf9 100644 --- a/phpBB/styles/prosilver/theme/images/announce_read_locked.gif +++ b/phpBB/styles/prosilver/theme/images/announce_read_locked.gif diff --git a/phpBB/styles/prosilver/theme/images/announce_read_locked_mine.gif b/phpBB/styles/prosilver/theme/images/announce_read_locked_mine.gifBinary files differ index 2105d21f10..e3f6e622a3 100644 --- a/phpBB/styles/prosilver/theme/images/announce_read_locked_mine.gif +++ b/phpBB/styles/prosilver/theme/images/announce_read_locked_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/announce_read_mine.gif b/phpBB/styles/prosilver/theme/images/announce_read_mine.gifBinary files differ index 2c88cacca0..d57e5d04e5 100644 --- a/phpBB/styles/prosilver/theme/images/announce_read_mine.gif +++ b/phpBB/styles/prosilver/theme/images/announce_read_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/announce_unread.gif b/phpBB/styles/prosilver/theme/images/announce_unread.gifBinary files differ index 33e10b2ccc..eb9edd1520 100644 --- a/phpBB/styles/prosilver/theme/images/announce_unread.gif +++ b/phpBB/styles/prosilver/theme/images/announce_unread.gif diff --git a/phpBB/styles/prosilver/theme/images/announce_unread_locked.gif b/phpBB/styles/prosilver/theme/images/announce_unread_locked.gifBinary files differ index 76dcc6ca71..054b0ae38d 100644 --- a/phpBB/styles/prosilver/theme/images/announce_unread_locked.gif +++ b/phpBB/styles/prosilver/theme/images/announce_unread_locked.gif diff --git a/phpBB/styles/prosilver/theme/images/announce_unread_locked_mine.gif b/phpBB/styles/prosilver/theme/images/announce_unread_locked_mine.gifBinary files differ index 53782fc3dc..a37b165b4f 100644 --- a/phpBB/styles/prosilver/theme/images/announce_unread_locked_mine.gif +++ b/phpBB/styles/prosilver/theme/images/announce_unread_locked_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/announce_unread_mine.gif b/phpBB/styles/prosilver/theme/images/announce_unread_mine.gifBinary files differ index bc07df0ce9..55f649cc4b 100644 --- a/phpBB/styles/prosilver/theme/images/announce_unread_mine.gif +++ b/phpBB/styles/prosilver/theme/images/announce_unread_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/forum_link.gif b/phpBB/styles/prosilver/theme/images/forum_link.gifBinary files differ index efeaf0a11f..42d445838b 100644 --- a/phpBB/styles/prosilver/theme/images/forum_link.gif +++ b/phpBB/styles/prosilver/theme/images/forum_link.gif diff --git a/phpBB/styles/prosilver/theme/images/forum_read.gif b/phpBB/styles/prosilver/theme/images/forum_read.gifBinary files differ index 845618c1a2..79d605ad7c 100644 --- a/phpBB/styles/prosilver/theme/images/forum_read.gif +++ b/phpBB/styles/prosilver/theme/images/forum_read.gif diff --git a/phpBB/styles/prosilver/theme/images/forum_read_locked.gif b/phpBB/styles/prosilver/theme/images/forum_read_locked.gifBinary files differ index 7afb092a8f..5eaf460a59 100644 --- a/phpBB/styles/prosilver/theme/images/forum_read_locked.gif +++ b/phpBB/styles/prosilver/theme/images/forum_read_locked.gif diff --git a/phpBB/styles/prosilver/theme/images/forum_read_subforum.gif b/phpBB/styles/prosilver/theme/images/forum_read_subforum.gifBinary files differ index 7119486539..b7b8176e4e 100644 --- a/phpBB/styles/prosilver/theme/images/forum_read_subforum.gif +++ b/phpBB/styles/prosilver/theme/images/forum_read_subforum.gif diff --git a/phpBB/styles/prosilver/theme/images/forum_unread.gif b/phpBB/styles/prosilver/theme/images/forum_unread.gifBinary files differ index 1a397cb216..8df11e7782 100644 --- a/phpBB/styles/prosilver/theme/images/forum_unread.gif +++ b/phpBB/styles/prosilver/theme/images/forum_unread.gif diff --git a/phpBB/styles/prosilver/theme/images/forum_unread_locked.gif b/phpBB/styles/prosilver/theme/images/forum_unread_locked.gifBinary files differ index 34f1d46ad7..63ac3fbedf 100644 --- a/phpBB/styles/prosilver/theme/images/forum_unread_locked.gif +++ b/phpBB/styles/prosilver/theme/images/forum_unread_locked.gif diff --git a/phpBB/styles/prosilver/theme/images/forum_unread_subforum.gif b/phpBB/styles/prosilver/theme/images/forum_unread_subforum.gifBinary files differ index e955887020..c5a2da1e31 100644 --- a/phpBB/styles/prosilver/theme/images/forum_unread_subforum.gif +++ b/phpBB/styles/prosilver/theme/images/forum_unread_subforum.gif diff --git a/phpBB/styles/prosilver/theme/images/sticky_read.gif b/phpBB/styles/prosilver/theme/images/sticky_read.gifBinary files differ index e1af585da5..c56a3833f9 100644 --- a/phpBB/styles/prosilver/theme/images/sticky_read.gif +++ b/phpBB/styles/prosilver/theme/images/sticky_read.gif diff --git a/phpBB/styles/prosilver/theme/images/sticky_read_locked.gif b/phpBB/styles/prosilver/theme/images/sticky_read_locked.gifBinary files differ index 79f581be79..854a8f06de 100644 --- a/phpBB/styles/prosilver/theme/images/sticky_read_locked.gif +++ b/phpBB/styles/prosilver/theme/images/sticky_read_locked.gif diff --git a/phpBB/styles/prosilver/theme/images/sticky_read_locked_mine.gif b/phpBB/styles/prosilver/theme/images/sticky_read_locked_mine.gifBinary files differ index ad056086e5..0d559c0767 100644 --- a/phpBB/styles/prosilver/theme/images/sticky_read_locked_mine.gif +++ b/phpBB/styles/prosilver/theme/images/sticky_read_locked_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/sticky_read_mine.gif b/phpBB/styles/prosilver/theme/images/sticky_read_mine.gifBinary files differ index 8f5f28fe5e..3cd077355a 100644 --- a/phpBB/styles/prosilver/theme/images/sticky_read_mine.gif +++ b/phpBB/styles/prosilver/theme/images/sticky_read_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/sticky_unread.gif b/phpBB/styles/prosilver/theme/images/sticky_unread.gifBinary files differ index d62b3c0f3a..0d201657e3 100644 --- a/phpBB/styles/prosilver/theme/images/sticky_unread.gif +++ b/phpBB/styles/prosilver/theme/images/sticky_unread.gif diff --git a/phpBB/styles/prosilver/theme/images/sticky_unread_locked.gif b/phpBB/styles/prosilver/theme/images/sticky_unread_locked.gifBinary files differ index 5792b8649a..4535708752 100644 --- a/phpBB/styles/prosilver/theme/images/sticky_unread_locked.gif +++ b/phpBB/styles/prosilver/theme/images/sticky_unread_locked.gif diff --git a/phpBB/styles/prosilver/theme/images/sticky_unread_locked_mine.gif b/phpBB/styles/prosilver/theme/images/sticky_unread_locked_mine.gifBinary files differ index 93495770c8..bb14033781 100644 --- a/phpBB/styles/prosilver/theme/images/sticky_unread_locked_mine.gif +++ b/phpBB/styles/prosilver/theme/images/sticky_unread_locked_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/sticky_unread_mine.gif b/phpBB/styles/prosilver/theme/images/sticky_unread_mine.gifBinary files differ index e201a9f31f..c7ae656f02 100644 --- a/phpBB/styles/prosilver/theme/images/sticky_unread_mine.gif +++ b/phpBB/styles/prosilver/theme/images/sticky_unread_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_moved.gif b/phpBB/styles/prosilver/theme/images/topic_moved.gifBinary files differ index 3dafa46ed7..707b9f5d3d 100644 --- a/phpBB/styles/prosilver/theme/images/topic_moved.gif +++ b/phpBB/styles/prosilver/theme/images/topic_moved.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_read.gif b/phpBB/styles/prosilver/theme/images/topic_read.gifBinary files differ index 640d5396f8..a3b706eb11 100644 --- a/phpBB/styles/prosilver/theme/images/topic_read.gif +++ b/phpBB/styles/prosilver/theme/images/topic_read.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_read_hot.gif b/phpBB/styles/prosilver/theme/images/topic_read_hot.gifBinary files differ index dcb6f3bd60..d118fdcc4f 100644 --- a/phpBB/styles/prosilver/theme/images/topic_read_hot.gif +++ b/phpBB/styles/prosilver/theme/images/topic_read_hot.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_read_hot_mine.gif b/phpBB/styles/prosilver/theme/images/topic_read_hot_mine.gifBinary files differ index 1e5498a9be..2e16f96e33 100644 --- a/phpBB/styles/prosilver/theme/images/topic_read_hot_mine.gif +++ b/phpBB/styles/prosilver/theme/images/topic_read_hot_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_read_locked.gif b/phpBB/styles/prosilver/theme/images/topic_read_locked.gifBinary files differ index a47affb2f2..3154d38463 100644 --- a/phpBB/styles/prosilver/theme/images/topic_read_locked.gif +++ b/phpBB/styles/prosilver/theme/images/topic_read_locked.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_read_locked_mine.gif b/phpBB/styles/prosilver/theme/images/topic_read_locked_mine.gifBinary files differ index d6142f0ea7..ac0248c2be 100644 --- a/phpBB/styles/prosilver/theme/images/topic_read_locked_mine.gif +++ b/phpBB/styles/prosilver/theme/images/topic_read_locked_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_read_mine.gif b/phpBB/styles/prosilver/theme/images/topic_read_mine.gifBinary files differ index 18a1245b93..b0e9455d0e 100644 --- a/phpBB/styles/prosilver/theme/images/topic_read_mine.gif +++ b/phpBB/styles/prosilver/theme/images/topic_read_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_unread.gif b/phpBB/styles/prosilver/theme/images/topic_unread.gifBinary files differ index 3fa920b6fc..de500726ec 100644 --- a/phpBB/styles/prosilver/theme/images/topic_unread.gif +++ b/phpBB/styles/prosilver/theme/images/topic_unread.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_unread_hot.gif b/phpBB/styles/prosilver/theme/images/topic_unread_hot.gifBinary files differ index e712f6e827..1937164e08 100644 --- a/phpBB/styles/prosilver/theme/images/topic_unread_hot.gif +++ b/phpBB/styles/prosilver/theme/images/topic_unread_hot.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_unread_hot_mine.gif b/phpBB/styles/prosilver/theme/images/topic_unread_hot_mine.gifBinary files differ index fa8b167c64..28fdd88f4b 100644 --- a/phpBB/styles/prosilver/theme/images/topic_unread_hot_mine.gif +++ b/phpBB/styles/prosilver/theme/images/topic_unread_hot_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_unread_locked.gif b/phpBB/styles/prosilver/theme/images/topic_unread_locked.gifBinary files differ index 0a9768ba7d..177dae74f4 100644 --- a/phpBB/styles/prosilver/theme/images/topic_unread_locked.gif +++ b/phpBB/styles/prosilver/theme/images/topic_unread_locked.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_unread_locked_mine.gif b/phpBB/styles/prosilver/theme/images/topic_unread_locked_mine.gifBinary files differ index 916b60517e..2b6b854e33 100644 --- a/phpBB/styles/prosilver/theme/images/topic_unread_locked_mine.gif +++ b/phpBB/styles/prosilver/theme/images/topic_unread_locked_mine.gif diff --git a/phpBB/styles/prosilver/theme/images/topic_unread_mine.gif b/phpBB/styles/prosilver/theme/images/topic_unread_mine.gifBinary files differ index 4ca8492e74..fd16eeedef 100644 --- a/phpBB/styles/prosilver/theme/images/topic_unread_mine.gif +++ b/phpBB/styles/prosilver/theme/images/topic_unread_mine.gif diff --git a/phpBB/styles/prosilver/theme/responsive.css b/phpBB/styles/prosilver/theme/responsive.css index d71fd142e6..76033a5ce1 100644 --- a/phpBB/styles/prosilver/theme/responsive.css +++ b/phpBB/styles/prosilver/theme/responsive.css @@ -280,11 +280,6 @@  		margin: 5px 0 0;  	} -	.row .pagination { -		margin-top: 2px; -		margin-bottom: 2px; -	} -  	.row .pagination .ellipsis + li {  		display: none !important;  	} @@ -567,13 +562,11 @@  @media (max-width: 850px) {  	.postprofile { width: 28%; } + +  }  @media (min-width: 701px) and (max-width: 950px) { -	.row .pagination { -		margin-top: 2px; -		margin-bottom: 2px; -	}  	ul.topiclist dt {      	margin-right: -410px; @@ -588,3 +581,11 @@  	}  } +@media (max-width: 992px) { +	.row .pagination { +		text-align: left; +		float: left; +		margin-top: 4px; +		margin-bottom: 4px; +	} +} diff --git a/phpBB/styles/prosilver/theme/stylesheet.css b/phpBB/styles/prosilver/theme/stylesheet.css index f235f6030e..45eb5b6fc9 100644 --- a/phpBB/styles/prosilver/theme/stylesheet.css +++ b/phpBB/styles/prosilver/theme/stylesheet.css @@ -1,21 +1,21 @@  /*  phpBB3 Style Sheet      -------------------------------------------------------------- -	Style name:			prosilver (the default phpBB 3.1.x style) +	Style name:			prosilver (the default phpBB 3.2.x style)  	Based on style:  	Original author:	Tom Beddard ( http://www.subblue.com/ )  	Modified by:		phpBB Limited ( https://www.phpbb.com/ )      --------------------------------------------------------------  */ -@import url("normalize.css"); -@import url("base.css"); -@import url("utilities.css"); -@import url("common.css"); -@import url("links.css"); -@import url("content.css"); -@import url("buttons.css"); -@import url("cp.css"); -@import url("forms.css"); -@import url("icons.css"); -@import url("colours.css"); -@import url("responsive.css"); +@import url("normalize.css?v=3.2"); +@import url("base.css?v=3.2"); +@import url("utilities.css?v=3.2"); +@import url("common.css?v=3.2"); +@import url("links.css?v=3.2"); +@import url("content.css?v=3.2"); +@import url("buttons.css?v=3.2"); +@import url("cp.css?v=3.2"); +@import url("forms.css?v=3.2"); +@import url("icons.css?v=3.2"); +@import url("colours.css?v=3.2"); +@import url("responsive.css?v=3.2"); diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 0ab29315ee..03388c6454 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -435,9 +435,9 @@ $sql_array = array(  *									Author, Post time, Replies, Subject, Views  * @var	string	sort_dir			Either "a" for ascending or "d" for descending  * @since 3.1.0-a1 -* @change 3.1.0-RC4 Added forum_data var -* @change 3.1.4-RC1 Added forum_id, topics_count, sort_days, sort_key and sort_dir vars -* @change 3.1.9-RC1 Fix types of properties +* @changed 3.1.0-RC4 Added forum_data var +* @changed 3.1.4-RC1 Added forum_id, topics_count, sort_days, sort_key and sort_dir vars +* @changed 3.1.9-RC1 Fix types of properties  */  $vars = array(  	'forum_data', diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index 85eb653b5a..624fe4ca9c 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -171,7 +171,7 @@ $sql_ary = array(  * @var	int		guest_counter	Number of guests displayed  * @var	array	forum_data		Array with forum data  * @since 3.1.0-a1 -* @change 3.1.0-a2 Added vars guest_counter and forum_data +* @changed 3.1.0-a2 Added vars guest_counter and forum_data  */  $vars = array('sql_ary', 'show_guests', 'guest_counter', 'forum_data');  extract($phpbb_dispatcher->trigger_event('core.viewonline_modify_sql', compact($vars))); @@ -396,7 +396,7 @@ while ($row = $db->sql_fetchrow($result))  	* @var	string	location_url	Page url to displayed in the list  	* @var	array	forum_data		Array with forum data  	* @since 3.1.0-a1 -	* @change 3.1.0-a2 Added var forum_data +	* @changed 3.1.0-a2 Added var forum_data  	*/  	$vars = array('on_page', 'row', 'location', 'location_url', 'forum_data');  	extract($phpbb_dispatcher->trigger_event('core.viewonline_overwrite_location', compact($vars))); diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 01c5f9ed42..7510a1281d 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -703,7 +703,7 @@ $base_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=  * @var	int		total_posts			Topic total posts count  * @var	string	viewtopic_url		URL to the topic page  * @since 3.1.0-RC4 -* @change 3.1.2-RC1 Added viewtopic_url +* @changed 3.1.2-RC1 Added viewtopic_url  */  $vars = array(  	'base_url', @@ -1203,7 +1203,7 @@ $sql_ary = array(  * @var	int		start		Pagination information  * @var	array	sql_ary		The SQL array to get the data of posts and posters  * @since 3.1.0-a1 -* @change 3.1.0-a2 Added vars forum_id, topic_id, topic_data, post_list, sort_days, sort_key, sort_dir, start +* @changed 3.1.0-a2 Added vars forum_id, topic_id, topic_data, post_list, sort_days, sort_key, sort_dir, start  */  $vars = array(  	'forum_id', @@ -2015,9 +2015,9 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)  	* @var	array	post_row			Template block array of the post  	* @var	array	topic_data			Array with topic data  	* @since 3.1.0-a1 -	* @change 3.1.0-a3 Added vars start, current_row_number, end, attachments -	* @change 3.1.0-b3 Added topic_data array, total_posts -	* @change 3.1.0-RC3 Added poster_id +	* @changed 3.1.0-a3 Added vars start, current_row_number, end, attachments +	* @changed 3.1.0-b3 Added topic_data array, total_posts +	* @changed 3.1.0-RC3 Added poster_id  	*/  	$vars = array(  		'start', @@ -2115,7 +2115,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)  	* @var	array	post_row			Template block array of the post  	* @var	array	topic_data			Array with topic data  	* @since 3.1.0-a3 -	* @change 3.1.0-b3 Added topic_data array, total_posts +	* @changed 3.1.0-b3 Added topic_data array, total_posts  	*/  	$vars = array(  		'start', @@ -2278,7 +2278,7 @@ $page_title = $topic_data['topic_title'] . ($start ? ' - ' . sprintf($user->lang  * @var	int		start			Start offset used to calculate the page  * @var	array	post_list		Array with post_ids we are going to display  * @since 3.1.0-a1 -* @change 3.1.0-RC4 Added post_list var +* @changed 3.1.0-RC4 Added post_list var  */  $vars = array('page_title', 'topic_data', 'forum_id', 'start', 'post_list');  extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_page_title', compact($vars))); diff --git a/tests/di/create_container_test.php b/tests/di/create_container_test.php index aba7a3560b..1fd2cbd7ee 100644 --- a/tests/di/create_container_test.php +++ b/tests/di/create_container_test.php @@ -46,6 +46,7 @@ namespace  		{  			$container = $this->builder->get_container();  			$this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerBuilder', $container); +			$this->assertFalse($container->hasParameter('container_exception'));  			// Checks the core services  			$this->assertTrue($container->hasParameter('core')); @@ -54,7 +55,7 @@ namespace  			$this->assertTrue($container->isFrozen());  			// Checks inject_config -			$this->assertTrue($container->hasParameter('dbal.dbhost')); +			$this->assertTrue($container->hasParameter('core.table_prefix'));  			// Checks use_extensions  			$this->assertTrue($container->hasParameter('enabled')); diff --git a/tests/di/fixtures/config/production/container/environment.yml b/tests/di/fixtures/config/production/container/environment.yml index 4216b187cc..8281d9e941 100644 --- a/tests/di/fixtures/config/production/container/environment.yml +++ b/tests/di/fixtures/config/production/container/environment.yml @@ -10,6 +10,9 @@ services:          arguments:              - '@service_container' +    dbal.conn.driver: +        synthetic: true +      dispatcher:          class: phpbb\db\driver\container_mock diff --git a/tests/di/fixtures/config/test/container/environment.yml b/tests/di/fixtures/config/test/container/environment.yml index 7d528fed19..252117dd32 100644 --- a/tests/di/fixtures/config/test/container/environment.yml +++ b/tests/di/fixtures/config/test/container/environment.yml @@ -10,6 +10,9 @@ services:          arguments:              - '@service_container' +    dbal.conn.driver: +        synthetic: true +      dispatcher:          class: phpbb\db\driver\container_mock diff --git a/tests/di/fixtures/other_config/production/container/environment.yml b/tests/di/fixtures/other_config/production/container/environment.yml index 1170145b66..c0d2f87bab 100644 --- a/tests/di/fixtures/other_config/production/container/environment.yml +++ b/tests/di/fixtures/other_config/production/container/environment.yml @@ -10,6 +10,9 @@ services:          arguments:              - '@service_container' +    dbal.conn.driver: +        synthetic: true +      dispatcher:          class: phpbb\db\driver\container_mock diff --git a/tests/di/fixtures/other_config/test/container/environment.yml b/tests/di/fixtures/other_config/test/container/environment.yml index 6c36977d4d..b9f6d05018 100644 --- a/tests/di/fixtures/other_config/test/container/environment.yml +++ b/tests/di/fixtures/other_config/test/container/environment.yml @@ -10,6 +10,9 @@ services:          arguments:              - '@service_container' +    dbal.conn.driver: +        synthetic: true +      dispatcher:          class: phpbb\db\driver\container_mock diff --git a/tests/event/fixtures/trigger_many_vars.test b/tests/event/fixtures/trigger_many_vars.test index a624138588..5e0720d13b 100644 --- a/tests/event/fixtures/trigger_many_vars.test +++ b/tests/event/fixtures/trigger_many_vars.test @@ -34,7 +34,7 @@  	*				posting page via $template->assign_vars()  	* @var	object	message_parser	The message parser object  	* @since 3.1.0-a1 -	* @change 3.1.0-b3 Added vars post_data, moderators, mode, page_title, +	* @changed 3.1.0-b3 Added vars post_data, moderators, mode, page_title,  	*		s_topic_icons, form_enctype, s_action, s_hidden_fields,  	*		post_id, topic_id, forum_id, submit, preview, save, load,  	*		delete, cancel, refresh, error, page_data, message_parser diff --git a/tests/feed/attachments_base_test.php b/tests/feed/attachments_base_test.php new file mode 100644 index 0000000000..dd432d13f5 --- /dev/null +++ b/tests/feed/attachments_base_test.php @@ -0,0 +1,99 @@ +<?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. + * + */ + +require_once(dirname(__FILE__) . '/attachments_mock_feed.php'); + +class phpbb_feed_attachments_base_test extends phpbb_database_test_case +{ +	protected $filesystem; + +	/** @var \phpbb_feed_attachments_mock_feed */ +	protected $attachments_mocks_feed; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/../extension/fixtures/extensions.xml'); +	} + +	public function setUp() +	{ +		global $phpbb_root_path, $phpEx; + +		$this->filesystem = new \phpbb\filesystem(); +		$config = new \phpbb\config\config(array()); +		$user = new \phpbb\user( +			new \phpbb\language\language( +				new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx) +			), +			'\phpbb\datetime' +		); +		$feed_helper = new \phpbb\feed\helper($config, $user, $phpbb_root_path, $phpEx); +		$db = $this->new_dbal(); +		$cache = new \phpbb_mock_cache(); +		$auth = new \phpbb\auth\auth(); +		$content_visibility = new \phpbb\content_visibility( +			$auth, +			$config, +			new \phpbb_mock_event_dispatcher(), +			$db, +			$user, +			$phpbb_root_path, +			$phpEx, +			FORUMS_TABLE, +			POSTS_TABLE, +			TOPICS_TABLE, +			USERS_TABLE +		); + +		$this->attachments_mocks_feed = new \phpbb_feed_attachments_mock_feed( +			$feed_helper, +			$config, +			$db, +			$cache, +			$user, +			$auth, +			$content_visibility, +			new \phpbb_mock_event_dispatcher(), +			$phpEx +		); +	} + +	public function data_fetch_attachments() +	{ +		return array( +			array(array(0), array(0)), +			array(array(), array(1)), +			array(array(), array(), 'RuntimeException') +		); +	} + +	/** +	 * @dataProvider data_fetch_attachments +	 */ +	public function test_fetch_attachments($post_ids, $topic_ids, $expected_exception = false) +	{ +		$this->attachments_mocks_feed->post_ids = $post_ids; +		$this->attachments_mocks_feed->topic_ids = $topic_ids; + +		if ($expected_exception !== false) +		{ +			$this->setExpectedException($expected_exception); + +			$this->attachments_mocks_feed->get_sql(); +		} +		else +		{ +			$this->assertTrue($this->attachments_mocks_feed->get_sql()); +		} +	} +} diff --git a/tests/feed/attachments_mock_feed.php b/tests/feed/attachments_mock_feed.php new file mode 100644 index 0000000000..fb67a48f7c --- /dev/null +++ b/tests/feed/attachments_mock_feed.php @@ -0,0 +1,36 @@ +<?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. + * + */ + +/** + * Board wide feed (aka overall feed) + * + * This will give you the newest {$this->num_items} posts + * from the whole board. + */ +class phpbb_feed_attachments_mock_feed extends \phpbb\feed\attachments_base +{ +	public $topic_ids = array(); +	public $post_ids = array(); + +	function get_sql() +	{ +		parent::fetch_attachments($this->post_ids, $this->topic_ids); + +		return true; +	} + +	public function adjust_item(&$item_row, &$row) +	{ +		return array(); +	} +} diff --git a/tests/functional/acp_bbcodes_test.php b/tests/functional/acp_bbcodes_test.php new file mode 100644 index 0000000000..58681dfa07 --- /dev/null +++ b/tests/functional/acp_bbcodes_test.php @@ -0,0 +1,46 @@ +<?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. + * + */ + +/** + * @group functional + */ +class phpbb_functional_acp_bbcodes_test extends phpbb_functional_test_case +{ +	public function test_htmlspecialchars() +	{ +		$this->login(); +		$this->admin_login(); + +		// Create the BBCode +		$crawler = self::request('GET', 'adm/index.php?i=acp_bbcodes&sid=' . $this->sid . '&mode=bbcodes&action=add'); +		$form = $crawler->selectButton('Submit')->form(array( +			'bbcode_match' => '[mod="{TEXT1}"]{TEXT2}[/mod]', +			'bbcode_tpl'   => '<div>{TEXT1}</div><div>{TEXT2}</div>' +		)); +		self::submit($form); + +		// Test it in the "new topic" preview +		$crawler = self::request('GET', 'posting.php?mode=post&f=2&sid=' . $this->sid); +		$form = $crawler->selectButton('Preview')->form(array( +			'subject' => 'subject', +			'message' => '[mod=a]b[/mod][mod="c"]d[/mod]' +		)); +		$crawler = self::submit($form); + +		$html = $crawler->filter('#preview')->html(); +		$this->assertContains('<div>a</div>', $html); +		$this->assertContains('<div>b</div>', $html); +		$this->assertContains('<div>c</div>', $html); +		$this->assertContains('<div>d</div>', $html); +	} +} diff --git a/tests/functional/acp_smilies_test.php b/tests/functional/acp_smilies_test.php new file mode 100644 index 0000000000..ebe8717fa7 --- /dev/null +++ b/tests/functional/acp_smilies_test.php @@ -0,0 +1,43 @@ +<?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. + * + */ + +/** + * @group functional + */ +class phpbb_functional_acp_smilies_test extends phpbb_functional_test_case +{ +	public function test_htmlspecialchars() +	{ +		$this->login(); +		$this->admin_login(); + +		// Create the BBCode +		$crawler = self::request('GET', 'adm/index.php?i=acp_icons&sid=' . $this->sid . '&mode=smilies&action=edit&id=1'); +		$form = $crawler->selectButton('Submit')->form(array( +			'code[icon_e_biggrin.gif]'    => '>:D', +			'emotion[icon_e_biggrin.gif]' => '>:D' +		)); +		self::submit($form); + +		// Test it in the "new topic" preview +		$crawler = self::request('GET', 'posting.php?mode=post&f=2&sid=' . $this->sid); +		$form = $crawler->selectButton('Preview')->form(array( +			'subject' => 'subject', +			'message' => '>:D' +		)); +		$crawler = self::submit($form); + +		$html = $crawler->filter('#preview')->html(); +		$this->assertRegexp('(<img [^>]+ alt=">:D" title=">:D"[^>]*>)', $html); +	} +} diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php index b70d49cddd..88f8999005 100644 --- a/tests/functional/fileupload_remote_test.php +++ b/tests/functional/fileupload_remote_test.php @@ -100,8 +100,8 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case  		$upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);  		$upload->set_error_prefix('')  			->set_allowed_extensions(array('gif')) -			->set_max_filesize(1000); -		$file = $upload->handle_upload('files.types.remote', self::$root_url . 'styles/prosilver/theme/images/forum_read.gif'); +			->set_max_filesize(2000); +		$file = $upload->handle_upload('files.types.remote', self::$root_url . 'develop/test.gif');  		$this->assertEquals(0, sizeof($file->error));  		$this->assertTrue(file_exists($file->get('filename')));  		$this->assertTrue($file->is_uploaded()); @@ -114,7 +114,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case  		$upload->set_error_prefix('')  			->set_allowed_extensions(array('gif'))  			->set_max_filesize(100); -		$file = $upload->handle_upload('files.types.remote', self::$root_url . 'styles/prosilver/theme/images/forum_read.gif'); +		$file = $upload->handle_upload('files.types.remote', self::$root_url . 'develop/test.gif');  		$this->assertEquals(1, sizeof($file->error));  		$this->assertEquals('WRONG_FILESIZE', $file->error[0]);  	} diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php index 9dd8a1dc91..8e6328d1d3 100644 --- a/tests/functional/posting_test.php +++ b/tests/functional/posting_test.php @@ -87,6 +87,24 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case  	}  	/** +	 * @see https://tracker.phpbb.com/browse/PHPBB3-14962 +	 */ +	public function test_edit() +	{ +		$this->login(); +		$this->create_topic(2, 'Test Topic post', 'Test topic post'); + +		$url =  self::$client->getCrawler()->selectLink('Edit')->link()->getUri(); +		$post_id = $this->get_parameter_from_link($url, 'p'); +		$crawler = self::request('GET', "posting.php?mode=edit&f=2&p={$post_id}&sid={$this->sid}"); +		$form = $crawler->selectButton('Submit')->form(); +		$form->setValues(array('message' => 'Edited post')); +		$crawler = self::submit($form); + +		$this->assertContains('Edited post', $crawler->filter("#post_content{$post_id} .content")->text()); +	} + +	/**  	* @testdox max_quote_depth is applied to the text populating the posting form  	*/  	public function test_quote_depth_form() @@ -246,4 +264,45 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case  		// Test that the preview contains the correct link  		$this->assertEquals($url, $crawler->filter('#preview a')->attr('href'));  	} + +	public function test_allowed_schemes_links() +	{ +		$text = 'http://example.org/ tcp://localhost:22/ServiceName'; + +		$this->login(); +		$this->admin_login(); + +		// Post with default settings +		$crawler = self::request('GET', 'posting.php?mode=post&f=2'); +		$form = $crawler->selectButton('Preview')->form(array( +			'subject' => 'Test subject', +			'message' => $text, +		)); +		$crawler = self::submit($form); +		$this->assertContains( +			'<a href="http://example.org/" class="postlink">http://example.org/</a> tcp://localhost:22/ServiceName', +			$crawler->filter('#preview .content')->html() +		); + +		// Update allowed schemes +		$crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post'); +		$form = $crawler->selectButton('Submit')->form(); +		$values = $form->getValues(); +		$values['config[allowed_schemes_links]'] = 'https,tcp'; +		$form->setValues($values); +		$crawler = self::submit($form); +		$this->assertEquals(1, $crawler->filter('.successbox')->count()); + +		// Post with new settings +		$crawler = self::request('GET', 'posting.php?mode=post&f=2'); +		$form = $crawler->selectButton('Preview')->form(array( +			'subject' => 'Test subject', +			'message' => $text, +		)); +		$crawler = self::submit($form); +		$this->assertContains( +			'http://example.org/ <a href="tcp://localhost:22/ServiceName" class="postlink">tcp://localhost:22/ServiceName</a>', +			$crawler->filter('#preview .content')->html() +		); +	}  } diff --git a/tests/functions_privmsgs/get_max_setting_from_group_test.php b/tests/functions_privmsgs/get_max_setting_from_group_test.php index 3eb7866802..fbabf1222a 100644 --- a/tests/functions_privmsgs/get_max_setting_from_group_test.php +++ b/tests/functions_privmsgs/get_max_setting_from_group_test.php @@ -33,12 +33,12 @@ class phpbb_functions_privmsgs_get_max_setting_from_group_test extends phpbb_dat  	static public function get_max_setting_from_group_data()  	{  		return array( -			array(1, 0, 'message_limit'), +			array(1, 2, 'message_limit'),  			array(2, 2, 'message_limit'),  			array(3, 0, 'message_limit'),  			array(4, 0, 'message_limit'),  			array(5, 2, 'message_limit'), -			array(1, 0, 'max_recipients'), +			array(1, 4, 'max_recipients'),  			array(2, 4, 'max_recipients'),  			array(3, 0, 'max_recipients'),  			array(4, 5, 'max_recipients'), diff --git a/tests/mock/phpbb_di_container_builder.php b/tests/mock/phpbb_di_container_builder.php index 23dc3d1e8b..c78b41d8ec 100644 --- a/tests/mock/phpbb_di_container_builder.php +++ b/tests/mock/phpbb_di_container_builder.php @@ -27,4 +27,12 @@ class phpbb_mock_phpbb_di_container_builder extends \phpbb\di\container_builder  	{  		return $this->phpbb_root_path . '../../tmp/autoload.' . $this->php_ext;  	} + +	/** +	 * {@inheritdoc} +	 */ +	protected function inject_dbal_driver() +	{ +		return; +	}  } diff --git a/tests/pagination/pagination_test.php b/tests/pagination/pagination_test.php index 30b25913f7..2d7d1671a8 100644 --- a/tests/pagination/pagination_test.php +++ b/tests/pagination/pagination_test.php @@ -219,6 +219,12 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case  				0,  				'PAGE_OF-1-1',  			), +			array( +				'10', +				'10', +				'0', +				'PAGE_OF-1-1', +			),  		);  	} diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 63e7cb869a..79c0ac8038 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -755,6 +755,43 @@ EOT  		$this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring S_NUM_ROWS is correct after modification');  	} +	public function test_find_key_index() +	{ +		$this->template->set_filenames(array('test' => 'loop_nested.html')); + +		$this->template->assign_var('TEST_MORE', true); + +		// @todo Change this +		$this->template->assign_block_vars('outer', array('VARIABLE' => 'zero')); +		$this->template->assign_block_vars('outer', array('VARIABLE' => 'one')); +		$this->template->assign_block_vars('outer.middle', array('VARIABLE' => '1A')); +		$this->template->assign_block_vars('outer', array('VARIABLE' => 'two')); +		$this->template->assign_block_vars('outer.middle', array('VARIABLE' => '2A')); +		$this->template->assign_block_vars('outer.middle', array('VARIABLE' => '2B')); +		$this->template->assign_block_vars('outer', array('VARIABLE' => 'three')); +		$this->template->assign_block_vars('outer.middle', array('VARIABLE' => '3A')); +		$this->template->assign_block_vars('outer.middle', array('VARIABLE' => '3B')); +		$this->template->assign_block_vars('outer.middle', array('VARIABLE' => '3C')); + +		$expect = 'outer - 0 - zero[outer|4]outer - 1 - one[outer|4]middle - 0 - 1A[middle|1]outer - 2 - two[outer|4]middle - 0 - 2A[middle|2]middle - 1 - 2B[middle|2]outer - 3 - three[outer|4]middle - 0 - 3A[middle|3]middle - 1 - 3B[middle|3]middle - 2 - 3C[middle|3]'; +		$this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring template is built correctly before modification'); + +		$this->template->find_key_index('outer', false); + +		$this->assertEquals(0, $this->template->find_key_index('outer', false), 'Find index at the beginning of outer loop'); +		$this->assertEquals(1, $this->template->find_key_index('outer', 1), 'Find index by index in outer loop'); +		$this->assertEquals(2, $this->template->find_key_index('outer', array('VARIABLE' => 'two')), 'Find index by key in outer loop'); +		$this->assertEquals(3, $this->template->find_key_index('outer', true), 'Find index at the end of outer loop'); +		$this->assertEquals(false, $this->template->find_key_index('outer', 7), 'Find index out of bounds of outer loop'); + +		$this->assertEquals(false, $this->template->find_key_index('outer[0].middle', false), 'Find index at the beginning of middle loop, no middle block'); +		$this->assertEquals(false, $this->template->find_key_index('outer[1].middle', 1), 'Find index by index in inner loop, out of bounds'); +		$this->assertEquals(1, $this->template->find_key_index('outer[2].middle', array('VARIABLE' => '2B')), 'Find index by key in middle loop'); +		$this->assertEquals(2, $this->template->find_key_index('outer.middle', true), 'Find index at the end of middle loop'); + +		$this->assertEquals(false, $this->template->find_key_index('outer.wrong', true), 'Wrong middle block name'); +		$this->assertEquals(false, $this->template->find_key_index('wrong.middle', false), 'Wrong outer block name'); +	}  	public function assign_block_vars_array_data()  	{  		return array( diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index d5e78d1d60..eb56049515 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -291,6 +291,13 @@ class phpbb_functional_test_case extends phpbb_test_case  			}  		} +		$install_config_file = $phpbb_root_path . 'store/install_config.php'; + +		if (file_exists($install_config_file)) +		{ +			unlink($install_config_file); +		} +  		$container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx);  		$container = $container_builder  			->with_environment('installer') @@ -304,6 +311,7 @@ class phpbb_functional_test_case extends phpbb_test_case  				],  				'cache.driver.class' => 'phpbb\cache\driver\file'  			]) +			->with_config(new \phpbb\config_php_file($phpbb_root_path, $phpEx))  			->without_compiled_container()  			->get_container(); diff --git a/tests/test_framework/phpbb_ui_test_case.php b/tests/test_framework/phpbb_ui_test_case.php index e3f636679c..b875d3212b 100644 --- a/tests/test_framework/phpbb_ui_test_case.php +++ b/tests/test_framework/phpbb_ui_test_case.php @@ -78,14 +78,11 @@ class phpbb_ui_test_case extends phpbb_test_case  			self::markTestSkipped('phpbb_functional_url was not set in test_config and wasn\'t set as PHPBB_FUNCTIONAL_URL environment variable either.');  		} -		if (!self::$webDriver) -		{ -			try { -				$capabilities = DesiredCapabilities::firefox(); -				self::$webDriver = RemoteWebDriver::create(self::$host . ':' . self::$port, $capabilities); -			} catch (WebDriverCurlException $e) { -				self::markTestSkipped('PhantomJS webserver is not running.'); -			} +		try { +			$capabilities = DesiredCapabilities::firefox(); +			self::$webDriver = RemoteWebDriver::create(self::$host . ':' . self::$port, $capabilities); +		} catch (WebDriverCurlException $e) { +			self::markTestSkipped('PhantomJS webserver is not running.');  		}  		if (!self::$already_installed) @@ -146,9 +143,14 @@ class phpbb_ui_test_case extends phpbb_test_case  		}  	} -	static public function visit($path) +	public function getDriver() +	{ +		return self::$webDriver; +	} + +	public function visit($path)  	{ -		self::$webDriver->get(self::$root_url . $path); +		$this->getDriver()->get(self::$root_url . $path);  	}  	static protected function recreate_database($config) @@ -157,14 +159,14 @@ class phpbb_ui_test_case extends phpbb_test_case  		$db_conn_mgr->recreate_db();  	} -	static public function find_element($type, $value) +	public function find_element($type, $value)  	{ -		return self::$webDriver->findElement(WebDriverBy::$type($value)); +		return $this->getDriver()->findElement(WebDriverBy::$type($value));  	} -	static public function submit($type = 'id', $value = 'submit') +	public function submit($type = 'id', $value = 'submit')  	{ -		$element = self::find_element($type, $value); +		$element = $this->find_element($type, $value);  		$element->click();  	} @@ -305,21 +307,21 @@ class phpbb_ui_test_case extends phpbb_test_case  		$ext_path = str_replace('/', '%2F', $extension);  		$this->visit('adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=' . $ext_path . '&sid=' . $this->sid); -		$this->assertNotEmpty(count(self::find_element('cssSelector', '.submit-buttons'))); +		$this->assertNotEmpty(count($this->find_element('cssSelector', '.submit-buttons'))); -		self::find_element('cssSelector', "input[value='Enable']")->submit(); +		$this->find_element('cssSelector', "input[value='Enable']")->submit();  		$this->add_lang('acp/extensions');  		try  		{ -			$meta_refresh = self::find_element('cssSelector', 'meta[http-equiv="refresh"]'); +			$meta_refresh = $this->find_element('cssSelector', 'meta[http-equiv="refresh"]');  			// Wait for extension to be fully enabled  			while (sizeof($meta_refresh))  			{  				preg_match('#url=.+/(adm+.+)#', $meta_refresh->getAttribute('content'), $match); -				self::$webDriver->execute(array('method' => 'post', 'url' => $match[1])); -				$meta_refresh = self::find_element('cssSelector', 'meta[http-equiv="refresh"]'); +				$this->getDriver()->execute(array('method' => 'post', 'url' => $match[1])); +				$meta_refresh = $this->find_element('cssSelector', 'meta[http-equiv="refresh"]');  			}  		}  		catch (\Facebook\WebDriver\Exception\NoSuchElementException $e) @@ -327,7 +329,7 @@ class phpbb_ui_test_case extends phpbb_test_case  			// Probably no refresh triggered  		} -		$this->assertContainsLang('EXTENSION_ENABLE_SUCCESS', self::find_element('cssSelector', 'div.successbox')->getText()); +		$this->assertContainsLang('EXTENSION_ENABLE_SUCCESS', $this->find_element('cssSelector', 'div.successbox')->getText());  		$this->logout();  	} @@ -415,7 +417,7 @@ class phpbb_ui_test_case extends phpbb_test_case  		}  		$this->visit('ucp.php?sid=' . $this->sid . '&mode=logout'); -		$this->assertContains($this->lang('REGISTER'), self::$webDriver->getPageSource()); +		$this->assertContains($this->lang('REGISTER'), $this->getDriver()->getPageSource());  		unset($this->sid);  	} @@ -435,17 +437,17 @@ class phpbb_ui_test_case extends phpbb_test_case  			return;  		} -		self::$webDriver->manage()->deleteAllCookies(); +		$this->getDriver()->manage()->deleteAllCookies();  		$this->visit('adm/index.php?sid=' . $this->sid); -		$this->assertContains($this->lang('LOGIN_ADMIN_CONFIRM'), self::$webDriver->getPageSource()); +		$this->assertContains($this->lang('LOGIN_ADMIN_CONFIRM'), $this->getDriver()->getPageSource()); -		self::find_element('cssSelector', 'input[name=username]')->clear()->sendKeys($username); -		self::find_element('cssSelector', 'input[type=password]')->sendKeys($username . $username); -		self::find_element('cssSelector', 'input[name=login]')->click(); +		$this->find_element('cssSelector', 'input[name=username]')->clear()->sendKeys($username); +		$this->find_element('cssSelector', 'input[type=password]')->sendKeys($username . $username); +		$this->find_element('cssSelector', 'input[name=login]')->click();  		$this->assertContains($this->lang('ADMIN_PANEL'), $this->find_element('cssSelector', 'h1')->getText()); -		$cookies = self::$webDriver->manage()->getCookies(); +		$cookies = $this->getDriver()->manage()->getCookies();  		// The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie  		foreach ($cookies as $cookie) @@ -550,19 +552,19 @@ class phpbb_ui_test_case extends phpbb_test_case  	{  		$this->add_lang('ucp'); -		self::$webDriver->manage()->deleteAllCookies(); +		$this->getDriver()->manage()->deleteAllCookies();  		$this->visit('ucp.php'); -		$this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), self::$webDriver->getPageSource()); +		$this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), $this->getDriver()->getPageSource()); -		self::$webDriver->manage()->deleteAllCookies(); +		$this->getDriver()->manage()->deleteAllCookies(); -		self::find_element('cssSelector', 'input[name=username]')->sendKeys($username); -		self::find_element('cssSelector', 'input[name=password]')->sendKeys($username . $username); -		self::find_element('cssSelector', 'input[name=login]')->click(); +		$this->find_element('cssSelector', 'input[name=username]')->sendKeys($username); +		$this->find_element('cssSelector', 'input[name=password]')->sendKeys($username . $username); +		$this->find_element('cssSelector', 'input[name=login]')->click();  		$this->assertNotContains($this->lang('LOGIN'), $this->find_element('className', 'navbar')->getText()); -		$cookies = self::$webDriver->manage()->getCookies(); +		$cookies = $this->getDriver()->manage()->getCookies();  		// The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie  		foreach ($cookies as $cookie) @@ -586,6 +588,6 @@ class phpbb_ui_test_case extends phpbb_test_case  		// Change the Path to your own settings  		$screenshot = time() . ".png"; -		self::$webDriver->takeScreenshot($screenshot); +		$this->getDriver()->takeScreenshot($screenshot);  	}  } diff --git a/tests/text_formatter/s9e/default_formatting_test.php b/tests/text_formatter/s9e/default_formatting_test.php index e25c3246b5..a0c57214e4 100644 --- a/tests/text_formatter/s9e/default_formatting_test.php +++ b/tests/text_formatter/s9e/default_formatting_test.php @@ -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="smilies" draggable="false" width="18" height="18" 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/svg/1f600.svg">'  			),  			array(  				"Emoji: \xF0\x9F\x98\x80", diff --git a/tests/text_processing/tickets_data/PHPBB3-14790.html b/tests/text_processing/tickets_data/PHPBB3-14790.html new file mode 100644 index 0000000000..7624b2d36c --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-14790.html @@ -0,0 +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 diff --git a/tests/text_processing/tickets_data/PHPBB3-14790.txt b/tests/text_processing/tickets_data/PHPBB3-14790.txt new file mode 100644 index 0000000000..1cd83d97d8 --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-14790.txt @@ -0,0 +1,4 @@ +[color=#0000FF][list][*]text +[*]text +[*]text +[*]text[/list][/color]
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-15008.before.php b/tests/text_processing/tickets_data/PHPBB3-15008.before.php new file mode 100644 index 0000000000..a3243e74cd --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-15008.before.php @@ -0,0 +1,18 @@ +<?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. +* +*/ + +function before_assert_phpbb3_15008($vars) +{ +	extract($vars); +	$parser->disable_smilies(); +} diff --git a/tests/text_processing/tickets_data/PHPBB3-15008.html b/tests/text_processing/tickets_data/PHPBB3-15008.html new file mode 100644 index 0000000000..7642eb63ee --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-15008.html @@ -0,0 +1 @@ +No smilies :) or shortnames :strawberry:
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-15008.txt b/tests/text_processing/tickets_data/PHPBB3-15008.txt new file mode 100644 index 0000000000..7642eb63ee --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-15008.txt @@ -0,0 +1 @@ +No smilies :) or shortnames :strawberry:
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-15016.html b/tests/text_processing/tickets_data/PHPBB3-15016.html new file mode 100644 index 0000000000..47b66ad771 --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-15016.html @@ -0,0 +1 @@ +<img class="smilies" src="phpBB/images/smilies/icon_lol.gif" width="15" height="17" alt=")--(" title=")--("> <img class="smilies" src="phpBB/images/smilies/icon_lol.gif" width="15" height="17" alt=")-(" title=")-("> <img class="smilies" src="phpBB/images/smilies/icon_lol.gif" width="15" height="17" alt=")--" title=")--">
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-15016.txt b/tests/text_processing/tickets_data/PHPBB3-15016.txt new file mode 100644 index 0000000000..081d9e3dc9 --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-15016.txt @@ -0,0 +1 @@ +)--( )-( )--
\ No newline at end of file diff --git a/tests/text_processing/tickets_data/PHPBB3-15016.xml b/tests/text_processing/tickets_data/PHPBB3-15016.xml new file mode 100644 index 0000000000..644481861e --- /dev/null +++ b/tests/text_processing/tickets_data/PHPBB3-15016.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_smilies"> +		<column>smiley_id</column> +		<column>code</column> +		<column>emotion</column> +		<column>smiley_url</column> +		<column>smiley_width</column> +		<column>smiley_height</column> +		<column>smiley_order</column> +		<column>display_on_posting</column> +		<row> +			<value>1</value> +			<value>)--(</value> +			<value>)--(</value> +			<value>icon_lol.gif</value> +			<value>15</value> +			<value>17</value> +			<value>22</value> +			<value>1</value> +		</row> +		<row> +			<value>2</value> +			<value>)--</value> +			<value>)--</value> +			<value>icon_lol.gif</value> +			<value>15</value> +			<value>17</value> +			<value>22</value> +			<value>1</value> +		</row> +		<row> +			<value>3</value> +			<value>)-(</value> +			<value>)-(</value> +			<value>icon_lol.gif</value> +			<value>15</value> +			<value>17</value> +			<value>22</value> +			<value>1</value> +		</row> +	</table> +</dataset> diff --git a/tests/ui/permission_roles_test.php b/tests/ui/permission_roles_test.php index 3501124fc1..de54cc788d 100644 --- a/tests/ui/permission_roles_test.php +++ b/tests/ui/permission_roles_test.php @@ -25,19 +25,19 @@ class ui_permission_roles_test extends phpbb_ui_test_case  		$this->visit('adm/index.php?i=acp_permissions&mode=setting_forum_local&sid=' . $this->sid);  		// Select forums -		$elements = self::find_element('cssSelector', 'select#forum') +		$elements = $this->find_element('cssSelector', 'select#forum')  			->findElements(\Facebook\WebDriver\WebDriverBy::tagName('option'));  		foreach ($elements as $element)  		{  			$element->click();  		} -		self::find_element('cssSelector', 'form#select_victim') +		$this->find_element('cssSelector', 'form#select_victim')  			->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('input[type=submit]'))  			->click();  		// Select administrators and guests -		$groups_form = self::find_element('cssSelector', 'form#groups'); +		$groups_form = $this->find_element('cssSelector', 'form#groups');  		$elements = $groups_form  			->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('select'))  			->findElements(\Facebook\WebDriver\WebDriverBy::tagName('option')); @@ -51,7 +51,7 @@ class ui_permission_roles_test extends phpbb_ui_test_case  		}  		$groups_form->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('input[name=submit_edit_options]'))->click(); -		$first_fieldset = self::find_element('cssSelector', '#perm11'); +		$first_fieldset = $this->find_element('cssSelector', '#perm11');  		$this->assertEquals('none', $first_fieldset->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('div.dropdown'))->getCSSValue('display'));  		$first_fieldset  			->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('span.dropdown-toggle')) @@ -74,14 +74,14 @@ class ui_permission_roles_test extends phpbb_ui_test_case  		$this->assertEquals($this->lang('ROLE_FORUM_LIMITED'), $first_fieldset->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('span.dropdown-toggle'))->getText());  		// Check that admin settings didn't get changed -		$second_fieldset = self::find_element('cssSelector', '#perm10'); +		$second_fieldset = $this->find_element('cssSelector', '#perm10');  		$this->assertEquals('none', $second_fieldset->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('div.dropdown'))->getCSSValue('display'));  		// Full access = 14  		$this->assertEquals(14, $second_fieldset->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('input[type=hidden]'))->getAttribute('value'));  		$this->assertEquals($this->lang('ROLE_FORUM_FULL'), $second_fieldset->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('span.dropdown-toggle'))->getText());  		// Check that category settings were not modified -		$category_fieldset = self::find_element('cssSelector', '#perm00'); +		$category_fieldset = $this->find_element('cssSelector', '#perm00');  		$this->assertEquals('none', $category_fieldset->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('div.dropdown'))->getCSSValue('display'));  		// No settings  		$this->assertEquals('', $category_fieldset->findElement(\Facebook\WebDriver\WebDriverBy::cssSelector('input[type=hidden]'))->getAttribute('value')); diff --git a/tests/ui/quick_links_test.php b/tests/ui/quick_links_test.php index 582aeafcae..171ef3ca53 100644 --- a/tests/ui/quick_links_test.php +++ b/tests/ui/quick_links_test.php @@ -19,8 +19,8 @@ class quick_links_test extends phpbb_ui_test_case  	public function test_quick_links()  	{  		$this->visit('index.php'); -		$this->assertEmpty(self::find_element('className', 'dropdown')->getText()); -		self::find_element('className', 'dropdown-toggle')->click(); -		$this->assertNotNull(self::find_element('className', 'dropdown')->getText()); +		$this->assertEmpty($this->find_element('className', 'dropdown')->getText()); +		$this->find_element('className', 'dropdown-toggle')->click(); +		$this->assertNotNull($this->find_element('className', 'dropdown')->getText());  	}  } diff --git a/tests/version/version_test.php b/tests/version/version_test.php index 93d47a40a6..abe51ef539 100644 --- a/tests/version/version_test.php +++ b/tests/version/version_test.php @@ -341,4 +341,209 @@ class phpbb_version_helper_test extends phpbb_test_case  		$this->assertSame($expected, $version_helper->get_latest_on_current_branch());  	} + +	public function get_update_on_branch_data() +	{ +		return array( +			array( +				'1.0.0', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +					), +					'1.1'	=> array( +						'current'		=> '1.1.1', +					), +				), +				array( +					'current'		=> '1.0.1', +				), +			), +			array( +				'1.0.1', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +					), +					'1.1'	=> array( +						'current'		=> '1.1.1', +					), +				), +				array(), +			), +			array( +				'1.0.1-a1', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1-a2', +					), +					'1.1'	=> array( +						'current'		=> '1.1.0', +					), +				), +				array( +					'current'		=> '1.0.1-a2', +				), +			), +			array( +				'1.1.0', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +					), +					'1.1'	=> array( +						'current'		=> '1.1.1', +					), +				), +				array( +					'current'		=> '1.1.1', +				), +			), +			array( +				'1.1.1', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +					), +					'1.1'	=> array( +						'current'		=> '1.1.1', +					), +				), +				array(), +			), +			array( +				'1.1.0-a1', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +					), +					'1.1'	=> array( +						'current'		=> '1.1.0-a2', +					), +				), +				array( +					'current'		=> '1.1.0-a2', +				), +			), +			array( +				'1.1.0', +				array(), +				array(), +			), +			// Latest safe release is 1.0.1 +			array( +				'1.0.0', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +						'security'		=> '1.0.1', +					), +					'1.1'	=> array( +						'current'		=> '1.1.1', +					), +				), +				array( +					'current'		=> '1.0.1', +					'security'		=> '1.0.1', +				), +			), +			// Latest safe release is 1.0.0 +			array( +				'1.0.0', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +						'security'		=> '1.0.0', +					), +					'1.1'	=> array( +						'current'		=> '1.1.1', +					), +				), +				array( +					'current'		=> '1.0.1', +					'security'		=> '1.0.0', +				), +			), +			// Latest safe release is 1.1.0 +			array( +				'1.0.0', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +						'security'		=> '1.1.0', +					), +					'1.1'	=> array( +						'current'		=> '1.1.1', +					), +				), +				array( +					'current'		=> '1.1.1', +				), +			), +			// Latest 1.0 release is EOL +			array( +				'1.0.0', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +						'eol'			=> true, +					), +					'1.1'	=> array( +						'current'		=> '1.1.1', +					), +				), +				array( +					'current'		=> '1.1.1', +				), +			), +			// All are EOL -- somewhat undefined behavior +			array( +				'1.0.0', +				array( +					'1.0'	=> array( +						'current'		=> '1.0.1', +						'eol'			=> true, +					), +					'1.1'	=> array( +						'current'		=> '1.1.1', +						'eol'			=> true, +					), +				), +				array(), +			), +		); +	} + +	/** +	 * @dataProvider get_update_on_branch_data +	 */ +	public function test_get_update_on_branch($current_version, $versions, $expected) +	{ +		global $phpbb_root_path, $phpEx; + +		$lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); +		$lang = new \phpbb\language\language($lang_loader); + +		$version_helper = $this +			->getMockBuilder('\phpbb\version_helper') +			->setMethods(array( +				'get_versions_matching_stability', +			)) +			->setConstructorArgs(array( +				$this->cache, +				new \phpbb\config\config(array( +					'version'	=> $current_version, +				)), +				new \phpbb\file_downloader(), +				new \phpbb\user($lang, '\phpbb\datetime'), +			)) +			->getMock() +		; + +		$version_helper->expects($this->any()) +			->method('get_versions_matching_stability') +			->will($this->returnValue($versions)); + +		$this->assertSame($expected, $version_helper->get_update_on_branch()); +	}  } | 
